[tor-commits] [flashproxy/rtmfp] Do RTMFP client and proxy using the new RTMFPSocket and ProxyPair.

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


commit b631fc0bc82957e07ad2a18ca1747eced2d6ca6e
Author: David Fifield <david at bamsoftware.com>
Date:   Sun Jun 12 00:25:39 2011 -0700

    Do RTMFP client and proxy using the new RTMFPSocket and ProxyPair.
---
 swfcat.as |  294 ++++++++++++++++++++++++++++++++++---------------------------
 1 files changed, 163 insertions(+), 131 deletions(-)

diff --git a/swfcat.as b/swfcat.as
index ac52ec8..6125187 100644
--- a/swfcat.as
+++ b/swfcat.as
@@ -5,26 +5,24 @@ package
     import flash.display.StageScaleMode;
     import flash.text.TextField;
     import flash.text.TextFormat;
+    import flash.net.Socket;
+    import flash.net.URLLoader;
+    import flash.net.URLLoaderDataFormat;
+    import flash.net.URLRequest;
+    import flash.net.URLRequestMethod;
+    import flash.net.URLVariables;
     import flash.events.Event;
+    import flash.events.IOErrorEvent;
+    import flash.events.SecurityErrorEvent;
     import flash.utils.setTimeout;
 
-    import FacilitatorSocket;
-    import events.FacilitatorSocketEvent;
-    
-    import ProxyPair;
-    import RTMFPProxyPair;
-    import TCPProxyPair;
-
-    import rtmfp.CirrusSocket;
-    import rtmfp.events.CirrusSocketEvent;
-
     public class swfcat extends Sprite
     {
         /* Adobe's Cirrus server for RTMFP connections.
            The Cirrus key is defined at compile time by
            reading from the CIRRUS_KEY environment var. */
-        private const DEFAULT_CIRRUS_ADDR:String = "rtmfp://p2p.rtmfp.net";
-        private const DEFAULT_CIRRUS_KEY:String = RTMFP::CIRRUS_KEY;
+        private const CIRRUS_URL:String = "rtmfp://p2p.rtmfp.net";
+        private const CIRRUS_KEY:String = RTMFP::CIRRUS_KEY;
         
         private const DEFAULT_FACILITATOR_ADDR:Object = {
             host: "tor-facilitator.bamsoftware.com",
@@ -47,17 +45,6 @@ package
         // Seconds.
         private const RATE_LIMIT_HISTORY:Number = 5.0;
 
-        // Socket to Cirrus server
-        private var s_c:CirrusSocket;
-        // Socket to facilitator.
-        private var s_f:FacilitatorSocket;
-        // Handle local-remote traffic
-        private var p_p:ProxyPair;
-        
-        private var client_id:String;
-        private var proxy_pair_factory:Function;
-        private var relay_addr:Object;
-        
         private var proxy_mode:Boolean;
 
         /* TextField for debug output. */
@@ -124,7 +111,10 @@ package
                 return;
             }
 
-            main();
+            if (proxy_mode)
+                proxy_main();
+            else
+                client_main();
         }
 
         /* Get an address structure from the given movie parameter, or the given
@@ -141,129 +131,171 @@ package
         }
 
         /* The main logic begins here, after start-up issues are taken care of. */
-        private function main():void
+        private function proxy_main():void
         {
-            if (proxy_mode) {
-                establish_facilitator_connection();
-            } else {
-                establish_cirrus_connection();
+            var fac_url:String;
+            var loader:URLLoader;
+
+            if (num_proxy_pairs >= MAX_NUM_PROXY_PAIRS) {
+                setTimeout(proxy_main, FACILITATOR_POLL_INTERVAL);
+                return;
             }
-        }
 
-        private function establish_cirrus_connection():void
-        {
-            s_c = new CirrusSocket();
-            s_c.addEventListener(CirrusSocketEvent.CONNECT_SUCCESS, function (e:CirrusSocketEvent):void {
-                puts("Cirrus: connected with id " + s_c.id + ".");
-                if (proxy_mode) {
-                    start_proxy_pair();
-                    s_c.send_hello(client_id);
-                } else {
-                    establish_facilitator_connection();
-                }
-            });
-            s_c.addEventListener(CirrusSocketEvent.CONNECT_FAILED, function (e:CirrusSocketEvent):void {
-                puts("Error: failed to connect to Cirrus.");
-            });
-            s_c.addEventListener(CirrusSocketEvent.CONNECT_CLOSED, function (e:CirrusSocketEvent):void {
-                puts("Cirrus: closed connection.");
+            loader = new URLLoader();
+            /* Get the x-www-form-urlencoded values. */
+            loader.dataFormat = URLLoaderDataFormat.VARIABLES;
+            loader.addEventListener(Event.COMPLETE, fac_complete);
+            loader.addEventListener(IOErrorEvent.IO_ERROR, function (e:IOErrorEvent):void {
+                puts("Facilitator: I/O error: " + e.text + ".");
             });
-            s_c.addEventListener(CirrusSocketEvent.HELLO_RECEIVED, function (e:CirrusSocketEvent):void {
-                puts("Cirrus: received hello from peer " + e.peer);
-                
-                /* don't bother if we already have a proxy going */
-                if (p_p != null && p_p.connected) {
-                    return;
-                }
-                
-                /* if we're in proxy mode, we should have already set
-                   up a proxy pair */
-                if (!proxy_mode) {
-                    relay_addr = DEFAULT_TOR_CLIENT_ADDR;
-                    proxy_pair_factory = rtmfp_proxy_pair_factory;
-                    start_proxy_pair();
-                    s_c.send_hello(e.peer);
-                } else {
-                    num_proxy_pairs++;
-                    badge.proxy_begin();
-                }
-                
-                p_p.client = {peer: e.peer, stream: e.stream};
+            loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, function (e:SecurityErrorEvent):void {
+                puts("Facilitator: security error: " + e.text + ".");
             });
-            
-            s_c.connect(DEFAULT_CIRRUS_ADDR, DEFAULT_CIRRUS_KEY);
+
+            fac_url = "http://" + encodeURIComponent(fac_addr.host)
+                + ":" + encodeURIComponent(fac_addr.port) + "/";
+            puts("Facilitator: connecting to " + fac_url + ".");
+            loader.load(new URLRequest(fac_url));
         }
 
-        private function establish_facilitator_connection():void
+        private function fac_complete(e:Event):void
         {
-            s_f = new FacilitatorSocket(fac_addr.host, fac_addr.port);
-            s_f.addEventListener(FacilitatorSocketEvent.CONNECT_FAILED, function (e:Event):void {
-                puts("Facilitator: connect failed.");
-                setTimeout(establish_facilitator_connection, FACILITATOR_POLL_INTERVAL);
-            });
-            
-            if (proxy_mode) {
-                s_f.addEventListener(FacilitatorSocketEvent.REGISTRATION_RECEIVED, function (e:FacilitatorSocketEvent):void {
-                    var client_addr:Object = parse_addr_spec(e.client);
-                    relay_addr = parse_addr_spec(e.relay);
-                    if (client_addr == null) {
-                        puts("Facilitator: got registration " + e.client);
-                        proxy_pair_factory = rtmfp_proxy_pair_factory;
-                        if (s_c == null || !s_c.connected) {
-                            client_id = e.client;
-                            establish_cirrus_connection();
-                        } else {
-                            start_proxy_pair();
-                            s_c.send_hello(e.client);
-                        }
-                    } else {
-                        proxy_pair_factory = tcp_proxy_pair_factory;
-                        start_proxy_pair();
-                        p_p.client = client_addr;
-                    }
-                });
-                s_f.addEventListener(FacilitatorSocketEvent.REGISTRATIONS_EMPTY, function (e:Event):void {
-                    puts("Facilitator: no registrations available.");
-                    setTimeout(establish_facilitator_connection, FACILITATOR_POLL_INTERVAL);
-                });
-                puts("Facilitator: getting registration.");
-                s_f.get_registration();
-            } else {
-                s_f.addEventListener(FacilitatorSocketEvent.REGISTRATION_FAILED, function (e:Event):void {
-                    puts("Facilitator: registration failed.");
-                    setTimeout(establish_facilitator_connection, FACILITATOR_POLL_INTERVAL);
-                });
-                puts("Facilitator: posting registration.");
-                s_f.post_registration(s_c.id);
+            var loader:URLLoader;
+            var client_spec:String;
+            var relay_spec:String;
+            var proxy_pair:Object;
+
+            setTimeout(proxy_main, FACILITATOR_POLL_INTERVAL);
+
+            loader = e.target as URLLoader;
+            client_spec = loader.data.client;
+            if (client_spec == "") {
+                puts("No clients.");
+                return;
+            } else if (!client_spec) {
+                puts("Error: missing \"client\" in response.");
+                return;
             }
+            relay_spec = loader.data.relay;
+            if (!relay_spec) {
+                puts("Error: missing \"relay\" in response.");
+                return;
+            }
+            puts("Facilitator: got client:\"" + client_spec + "\" "
+                + "relay:\"" + relay_spec + "\".");
+
+            try {
+                proxy_pair = make_proxy_pair(client_spec, relay_spec);
+            } catch (e:ArgumentError) {
+                puts("Error: " + e);
+                return;
+            }
+            proxy_pair.addEventListener(Event.COMPLETE, function(e:Event):void {
+                proxy_pair.log("Complete.");
+                num_proxy_pairs--;
+                badge.proxy_end();
+            });
+            proxy_pair.connect();
+
+            num_proxy_pairs++;
+            badge.proxy_begin();
         }
-        
-        private function start_proxy_pair():void
+
+        private function client_main():void
         {
-            p_p = proxy_pair_factory();
-            p_p.addEventListener(Event.CONNECT, function (e:Event):void {
-                puts("ProxyPair: connected!");
+            var rs:RTMFPSocket;
+
+            rs = new RTMFPSocket(CIRRUS_URL, CIRRUS_KEY);
+            rs.addEventListener(Event.COMPLETE, function (e:Event):void {
+                puts("Got RTMFP id " + rs.id);
+                register(rs);
             });
-            p_p.addEventListener(Event.CLOSE, function (e:Event):void {
-                puts("ProxyPair: connection closed.");
-                p_p = null;
-                if (proxy_mode) {
-                    num_proxy_pairs--;
-                    badge.proxy_end();
-                }
-                establish_facilitator_connection();
+            rs.addEventListener(RTMFPSocket.ACCEPT_EVENT, client_accept);
+
+            rs.listen();
+        }
+
+        private function client_accept(e:Event):void {
+            var rs:RTMFPSocket;
+            var s_t:Socket;
+            var proxy_pair:ProxyPair;
+
+            rs = e.target as RTMFPSocket;
+            s_t = new Socket();
+
+            puts("Got RTMFP connection from " + rs.peer_id);
+
+            proxy_pair = new ProxyPair(this, rs, function ():void {
+                /* Do nothing; already connected. */
+            }, s_t, function ():void {
+                s_t.connect(DEFAULT_TOR_CLIENT_ADDR.host, DEFAULT_TOR_CLIENT_ADDR.port);
             });
-            p_p.relay = relay_addr;
+            proxy_pair.connect();
         }
-        
-        private function rtmfp_proxy_pair_factory():ProxyPair
-        {
-            return new RTMFPProxyPair(this, s_c, s_c.local_stream_name);
+
+        private function register(rs:RTMFPSocket):void {
+            var fac_url:String;
+            var loader:URLLoader;
+            var request:URLRequest;
+            var variables:URLVariables;
+
+            loader = new URLLoader();
+            loader.addEventListener(Event.COMPLETE, function (e:Event):void {
+                puts("Facilitator: registered.");
+            });
+            loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, function (e:SecurityErrorEvent):void {
+                puts("Facilitator: security error: " + e.text + ".");
+                rs.close();
+            });
+            loader.addEventListener(IOErrorEvent.IO_ERROR, function (e:IOErrorEvent):void {
+                puts("Facilitator: I/O error: " + e.text + ".");
+                rs.close();
+            });
+
+            fac_url = "http://" + encodeURIComponent(fac_addr.host)
+                + ":" + encodeURIComponent(fac_addr.port) + "/";
+            request = new URLRequest(fac_url);
+            request.method = URLRequestMethod.POST;
+            request.data = new URLVariables;
+            request.data["client"] = rs.id;
+
+            puts("Facilitator: connecting to " + fac_url + ".");
+            loader.load(request);
         }
-        
-        private function tcp_proxy_pair_factory():ProxyPair
+
+        private function make_proxy_pair(client_spec:String, relay_spec:String):ProxyPair
         {
-            return new TCPProxyPair(this);
+            var addr_c:Object;
+            var addr_r:Object;
+            var s_c:*;
+            var s_r:Socket;
+
+            addr_r = swfcat.parse_addr_spec(relay_spec);
+            if (!addr_r)
+                throw new ArgumentError("Relay spec must be in the form \"host:port\".");
+
+            addr_c = swfcat.parse_addr_spec(client_spec);
+            if (addr_c) {
+                s_c = new Socket();
+                s_r = new Socket();
+                return new ProxyPair(this, s_c, function ():void {
+                    s_c.connect(addr_c.host, addr_c.port);
+                }, s_r, function ():void {
+                    s_r.connect(addr_r.host, addr_r.port);
+                });
+            }
+
+            if (client_spec.match(/^[0-9A-Fa-f]{64}$/)) {
+                s_c = new RTMFPSocket(CIRRUS_URL, CIRRUS_KEY);
+                s_r = new Socket();
+                return new ProxyPair(this, s_c, function ():void {
+                    s_c.connect(client_spec);
+                }, s_r, function ():void {
+                    s_r.connect(addr_r.host, addr_r.port);
+                });
+            }
+
+            throw new ArgumentError("Can't parse client spec \"" + client_spec + "\".");
         }
 
         /* Parse an address in the form "host:port". Returns an Object with





More information about the tor-commits mailing list