[tor-commits] [flashproxy/master] Initial version of AS Connector that communicates with Cirrus server and facilitator

dcf at torproject.org dcf at torproject.org
Sun Jun 12 08:56:27 UTC 2011


commit 9bcfc6f7a6ea6a94faed9becb1311ea94443727d
Author: Nate Hardison <nate at rescomp-09-154551.stanford.edu>
Date:   Wed May 4 18:25:39 2011 -0700

    Initial version of AS Connector that communicates with Cirrus server and facilitator
---
 Connector.as         |  137 ++++++++++++++++++++++++++++-
 Makefile             |    2 +-
 RTMFPRelay.as        |  235 +++++++-------------------------------------------
 RTMFPRelayReactor.as |   13 +++
 Utils.as             |   24 +++++
 5 files changed, 203 insertions(+), 208 deletions(-)

diff --git a/Connector.as b/Connector.as
index f362dd3..fc18692 100644
--- a/Connector.as
+++ b/Connector.as
@@ -16,9 +16,27 @@ package
     import flash.utils.setInterval;
     import flash.utils.setTimeout;
     
-    public class Connector extends RTMFPRelay {
+    import RTMFPRelay;
+    import RTMFPRelayReactor;
+    import Utils;
+    
+    public class Connector extends Sprite implements RTMFPRelayReactor {
+      
+      /* David's relay (nickname 3VXRyxz67OeRoqHn) that also serves a
+         crossdomain policy. */
+      private const DEFAULT_TOR_ADDR:Object = {
+          host: "173.255.221.44",
+          port: 9001
+      };
       
       private var output_text:TextField;
+
+      // Socket to Tor relay.
+      private var s_t:Socket;
+      // Socket to facilitator.
+      private var s_f:Socket;
+      // RTMFP data relay
+      private var relay:RTMFPRelay;
       
       private var fac_addr:Object;
       private var tor_addr:Object;
@@ -33,10 +51,70 @@ package
         addChild(output_text);
 
         puts("Starting.");
+        
         // Wait until the query string parameters are loaded.
         this.loaderInfo.addEventListener(Event.COMPLETE, loaderinfo_complete);
       }
       
+      private function facilitator_is(host:String, port:int):void
+      {
+        if (s_f != null && s_f.connected) {
+          puts("Error: already connected to Facilitator!");
+          return;
+        }
+        
+        s_f = new Socket();
+        
+        s_f.addEventListener(Event.CONNECT, function (e:Event):void {
+          puts("Facilitator: connected.");
+          onConnectionEvent();
+        });
+        s_f.addEventListener(Event.CLOSE, function (e:Event):void {
+          puts("Facilitator: closed connection.");
+        });
+        s_f.addEventListener(IOErrorEvent.IO_ERROR, function (e:IOErrorEvent):void {
+          puts("Facilitator: I/O error: " + e.text + ".");
+        });
+        s_f.addEventListener(SecurityErrorEvent.SECURITY_ERROR, function (e:SecurityErrorEvent):void {
+          puts("Facilitator: security error: " + e.text + ".");
+        });
+
+        puts("Facilitator: connecting to " + host + ":" + port + ".");
+        s_f.connect(host, port);
+      }
+      
+      private function tor_relay_is(host:String, port:int):void
+      {
+        if (s_t != null && s_t.connected) {
+          puts("Error: already connected to Tor relay!");
+          return;
+        }
+        
+        s_t = new Socket();
+
+        s_t.addEventListener(Event.CONNECT, function (e:Event):void {
+          puts("Tor: connected.");
+          onConnectionEvent();
+        });
+        s_t.addEventListener(Event.CLOSE, function (e:Event):void {
+          puts("Tor: closed.");
+        });
+        s_t.addEventListener(IOErrorEvent.IO_ERROR, function (e:IOErrorEvent):void {
+          puts("Tor: I/O error: " + e.text + ".");
+        });
+        s_t.addEventListener(SecurityErrorEvent.SECURITY_ERROR, function (e:SecurityErrorEvent):void {
+          puts("Tor: security error: " + e.text + ".");
+        });
+
+        puts("Tor: connecting to " + host + ":" + port + ".");
+        s_t.connect(host, port);
+      }
+
+      private function puts(s:String):void
+      {
+          output_text.appendText(s + "\n");
+          output_text.scrollV = output_text.maxScrollV;
+      }
       
       private function loaderinfo_complete(e:Event):void
       {
@@ -45,8 +123,61 @@ package
 
         puts("Parameters loaded.");
         
-        
+        fac_spec = this.loaderInfo.parameters["facilitator"];
+        if (!fac_spec) {
+            puts("Error: no \"facilitator\" specification provided.");
+            return;
+        }
+        puts("Facilitator spec: \"" + fac_spec + "\"");
+        fac_addr = Utils.parse_addr_spec(fac_spec);
+        if (!fac_addr) {
+            puts("Error: Facilitator spec must be in the form \"host:port\".");
+            return;
+        }
+
+        relay = new RTMFPRelay(this);
+
+        tor_addr = DEFAULT_TOR_ADDR;
+        tor_relay_is(tor_addr.host, tor_addr.port);
+        facilitator_is(fac_addr.host, fac_addr.port);
       }
-    
+      
+      public function onConnectionEvent():void
+      {
+        if (s_f != null && s_f.connected && s_t != null && s_t.connected && 
+            relay != null && relay.connected) {
+              s_f.writeUTFBytes("POST / HTTP/1.1\r\n\r\nclient=%3A"+ relay.cirrus_id + "\r\n");
+        }
+      }
+      
+      public function onIOErrorEvent(event:IOErrorEvent):void
+      {
+        puts("Cirrus: I/O error: " + event.text + ".");
+      }
+      
+      public function onNetStatusEvent(event:NetStatusEvent):void
+      {
+        switch (event.info.code) {
+  				case "NetConnection.Connect.Success" :
+  					puts("Cirrus: connected with ID " + relay.cirrus_id + ".");
+  					onConnectionEvent();
+  					break;
+  				case "NetStream.Connect.Success" :
+  				  puts("Peer: connected.");
+  					break;
+  				case "NetStream.Publish.BadName" :
+  					puts(event.info.code);
+  					break;
+  				case "NetStream.Connect.Closed" :
+  					puts(event.info.code);
+  					break;
+  			}
+      }
+      
+      public function onSecurityErrorEvent(event:SecurityErrorEvent):void
+      {
+        puts("Cirrus: security error: " + event.text + ".");
+      }
+  }
 }
     
\ No newline at end of file
diff --git a/Makefile b/Makefile
index baf0e94..92047fb 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 MXMLC ?= mxmlc
 
-TARGETS = swfcat.swf Proxy.swf
+TARGETS = swfcat.swf Connector.swf
 
 all: $(TARGETS)
 
diff --git a/RTMFPRelay.as b/RTMFPRelay.as
index 27b3208..a33ebbf 100644
--- a/RTMFPRelay.as
+++ b/RTMFPRelay.as
@@ -15,8 +15,6 @@ package
     import flash.utils.clearInterval;
     import flash.utils.setInterval;
     import flash.utils.setTimeout;
-    
-    import Utils;
 
     public class RTMFPRelay extends Sprite
     {
@@ -24,15 +22,8 @@ package
 		    private static const CIRRUS_DEV_KEY:String = RTMFP::CIRRUS_KEY;
 		
         /* The name of the "media" to pass between peers */
-        public static const DATA:String = "data";
+        private static const DATA:String = "data";
 		
-        protected var output_text:TextField;
-
-        // Socket to Tor relay.
-        private var s_t:Socket;
-        // Socket to facilitator.
-        private var s_f:Socket;
-
         /* Connection to the Cirrus rendezvous service */
         private var cirrus_conn:NetConnection;
 		
@@ -42,231 +33,67 @@ package
 		    /* Data streams to be established with peer */
 		    private var send_stream:NetStream;
 		    private var recv_stream:NetStream;
+		    
+		    private var notifiee:RTMFPRelayReactor;
 
-        private var fac_addr:Object;
-        private var tor_addr:Object;
-
-        private function puts(s:String):void
-        {
-            output_text.appendText(s + "\n");
-            output_text.scrollV = output_text.maxScrollV;
-        }
-
-        public function RTMFPRelay()
-        {
-            output_text = new TextField();
-            output_text.width = 400;
-            output_text.height = 300;
-            output_text.background = true;
-            output_text.backgroundColor = 0x001f0f;
-            output_text.textColor = 0x44CC44;
-            addChild(output_text);
-
-            puts("Starting.");
-            
-            cirrus_conn = new NetConnection();
-			      cirrus_conn.addEventListener(NetStatusEvent.NET_STATUS, function (e:NetStatusEvent):void {
-			        puts("Cirrus: connected.");
-			      });
-			      cirrus_conn.addEventListener(IOErrorEvent.IO_ERROR, function (e:IOErrorEvent):void {
-				      puts("Cirrus: I/O error: " + e.text + ".");
-			      });
-			
-			      cirrus_conn.addEventListener(SecurityErrorEvent.SECURITY_ERROR, function (e:SecurityError):void {
-				      puts("Cirrus: security error: " + e.text + ".");
-			      });
+        public function RTMFPRelay(notifiee:RTMFPRelayReactor)
+        {   
+          this.notifiee = notifiee;
+          
+          cirrus_conn = new NetConnection();
+			    cirrus_conn.addEventListener(NetStatusEvent.NET_STATUS, notifiee.onNetStatusEvent);
+			    cirrus_conn.addEventListener(IOErrorEvent.IO_ERROR, notifiee.onIOErrorEvent);
+			    cirrus_conn.addEventListener(SecurityErrorEvent.SECURITY_ERROR, notifiee.onSecurityErrorEvent);
 			
-			      cirrus_conn.connect(CIRRUS_ADDRESS + "/" + CIRRUS_DEV_KEY);
-            
-            
-            // Wait until the query string parameters are loaded.
-            this.loaderInfo.addEventListener(Event.COMPLETE, loaderinfo_complete);
+			    cirrus_conn.connect(CIRRUS_ADDRESS + "/" + CIRRUS_DEV_KEY);
         }
 
-        public function data_is(data:ByteArray):void
+        public function get cirrus_id():String
         {
+          if (cirrus_conn != null && cirrus_conn.connected) {
+            return cirrus_conn.nearID;
+          }
           
-          
+          return null;
         }
         
-        public function facilitator_is(host:String, port:String):void
+        public function get connected():Boolean
+        {
+          return (cirrus_conn != null && cirrus_conn.connected);
+        }
+
+        public function data_is(data:ByteArray):void
         {
-          if (s_f != null && s_f.connected) {
-            
-            return;
-          }
           
-          s_f = new Socket();
           
-          s_f.addEventListener(Event.CONNECT, function (e:Event):void {
-            puts("Facilitator: connected.");
-          });
-          s_f.addEventListener(Event.CLOSE, function (e:Event):void {
-            puts("Facilitator: closed connection.");
-          });
-          s_f.addEventListener(IOErrorEvent.IO_ERROR, function (e:IOErrorEvent):void {
-            puts("Facilitator: I/O error: " + e.text + ".");
-          });
-          s_f.addEventListener(SecurityErrorEvent.SECURITY_ERROR, function (e:SecurityErrorEvent):void {
-            puts("Facilitator: security error: " + e.text + ".");
-          });
-
-          puts("Facilitator: connecting to " + host + ":" + port + ".");
-          s_f.connect(host, port);
         }
         
-        public function peer(peer_id:String):String
+        public function get peer():String
         {
           return this.peer_id;
         }
 
-        public function peer_is(peer_id:String):void
+        public function set peer(peer_id:String):void
         {
           if (peer_id == null) {
-    				puts("Error: Client ID doesn't exist.");
-    				return;
+            throw new Error("Peer ID is null.")
     			} else if (peer_id == cirrus_conn.nearID) {
-    				puts("Error: Client ID is our ID.");
-    				return;
+    				throw new Error("Peer ID cannot be the same as our ID.");
     			} else if (this.peer_id == peer_id) {
-    			  
+    			  throw new Error("Already connected to peer " + peer_id + ".");
     			} else if (this.recv_stream != null) {
-            puts("Error: already set up with a peer!");
-            return;
+            throw new Error("Cannot connect to a second peer.");
           }
           
           this.peer_id = peer_id;
           
           send_stream = new NetStream(cirrus_conn, NetStream.DIRECT_CONNECTIONS);
-    			send_stream.addEventListener(NetStatusEvent.NET_STATUS, net_status_event_handler);
+    			send_stream.addEventListener(NetStatusEvent.NET_STATUS, notifiee.onNetStatusEvent);
     			send_stream.publish(DATA);
 
     			recv_stream = new NetStream(cirrus_conn, peer_id);
-    			recv_stream.addEventListener(NetStatusEvent.NET_STATUS, net_status_event_handler);
+    			recv_stream.addEventListener(NetStatusEvent.NET_STATUS, notifiee.onNetStatusEvent);
     			recv_stream.play(DATA);
         }
-        
-        public function tor_relay_is(host:String, port:String):void
-        {
-          if (s_t != null && s_t.connected) {
-            puts("Error: already connected to Tor relay!");
-            return;
-          }
-          
-          s_t = new Socket();
-
-          s_t.addEventListener(Event.CONNECT, function (e:Event):void {
-            puts("Tor: connected.");
-          });
-          s_t.addEventListener(Event.CLOSE, function (e:Event):void {
-            puts("Tor: closed.");
-          });
-          s_t.addEventListener(IOErrorEvent.IO_ERROR, function (e:IOErrorEvent):void {
-            puts("Tor: I/O error: " + e.text + ".");
-          });
-          s_t.addEventListener(SecurityErrorEvent.SECURITY_ERROR, function (e:SecurityErrorEvent):void {
-            puts("Tor: security error: " + e.text + ".");
-          });
-
-          puts("Tor: connecting to " + host + ":" + port + ".");
-          s_t.connect(host, port);
-        }
-
-        private function loaderinfo_complete(e:Event):void
-        {
-            var fac_spec:String;
-            var tor_spec:String;
-
-            puts("Parameters loaded.");
-            fac_spec = this.loaderInfo.parameters["facilitator"];
-            if (!fac_spec) {
-                puts("Error: no \"facilitator\" specification provided.");
-                return;
-            }
-            puts("Facilitator spec: \"" + fac_spec + "\"");
-            fac_addr = parse_addr_spec(fac_spec);
-            if (!fac_addr) {
-                puts("Error: Facilitator spec must be in the form \"host:port\".");
-                return;
-            }
-
-            tor_addr = DEFAULT_TOR_ADDR;
-
-            go();
-        }
-
-        private function fac_connected(e:Event):void
-        {
-            
-
-            s_f.addEventListener(ProgressEvent.SOCKET_DATA, function (e:ProgressEvent):void {
-              var client_spec:String;
-              var client_addr:Object;
-
-              client_spec = s_f.readMultiByte(e.bytesLoaded, "utf-8");
-              puts("Facilitator: got \"" + client_spec + "\"");
-
-              /*client_addr = parse_addr_spec(client_spec);
-              if (!client_addr) {
-                puts("Error: Client spec must be in the form \"host:port\".");
-                return;
-              }
-              if (client_addr.host == "0.0.0.0" && client_addr.port == 0) {
-                puts("Error: Facilitator has no clients.");
-                return;
-              }*/
-
-				      /* Now we have a client, so start up a connection to the Cirrus rendezvous point */
-				      
-            });
-
-            s_f.writeUTFBytes("GET / HTTP/1.0\r\n\r\n");
-        }
-		
-		private function net_status_event_handler(e:NetStatusEvent):void
-		{
-			switch (e.info.code) {
-				case "NetConnection.Connect.Success" :
-					// Cirrus is now connected
-					cirrus_connected(e);
-			}
-			
-		}
-		
-		private function cirrus_connected(e:Event):void
-		{
-			
-					
-			
-		}
-
-        /*private function client_connected(e:Event):void
-        {
-            puts("Client: connected.");
-
-            s_t.addEventListener(ProgressEvent.SOCKET_DATA, function (e:ProgressEvent):void {
-                var bytes:ByteArray = new ByteArray();
-                s_t.readBytes(bytes, 0, e.bytesLoaded);
-                puts("Tor: read " + bytes.length + ".");
-                s_c.writeBytes(bytes);
-            });
-            s_c.addEventListener(ProgressEvent.SOCKET_DATA, function (e:ProgressEvent):void {
-                var bytes:ByteArray = new ByteArray();
-                s_c.readBytes(bytes, 0, e.bytesLoaded);
-                puts("Client: read " + bytes.length + ".");
-                s_t.writeBytes(bytes);
-            });
-        }*/
-		
-		private function close_connections():void
-		{
-			if (s_t.connected) s_t.close();
-			if (s_f.connected) s_f.close();
-			if (cirrus.connected) cirrus.close();
-			if (send_stream != null) send_stream.close();
-			if (recv_stream != null) recv_stream.close();
-		}
-
-        
     }
 }
diff --git a/RTMFPRelayReactor.as b/RTMFPRelayReactor.as
new file mode 100644
index 0000000..5c84779
--- /dev/null
+++ b/RTMFPRelayReactor.as
@@ -0,0 +1,13 @@
+package {
+
+  import flash.events.IOErrorEvent;
+  import flash.events.NetStatusEvent;
+  import flash.events.SecurityErrorEvent;
+  
+  public interface RTMFPRelayReactor {
+    function onIOErrorEvent(event:IOErrorEvent):void;
+    function onNetStatusEvent(event:NetStatusEvent):void;
+    function onSecurityErrorEvent(event:SecurityErrorEvent):void
+  }
+  
+}
\ No newline at end of file
diff --git a/Utils.as b/Utils.as
new file mode 100644
index 0000000..75ed44c
--- /dev/null
+++ b/Utils.as
@@ -0,0 +1,24 @@
+package {
+  
+  public class Utils {
+    
+    /* Parse an address in the form "host:port". Returns an Object with
+       keys "host" (String) and "port" (int). Returns null on error. */
+    public static function parse_addr_spec(spec:String):Object
+    {
+        var parts:Array;
+        var addr:Object;
+
+        parts = spec.split(":", 2);
+        if (parts.length != 2 || !parseInt(parts[1]))
+            return null;
+        addr = {}
+        addr.host = parts[0];
+        addr.port = parseInt(parts[1]);
+
+        return addr;
+    }
+    
+  }
+  
+}
\ No newline at end of file





More information about the tor-commits mailing list