[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [flashproxy/rtmfp] Do RTMFP client and proxy using the new RTMFPSocket and ProxyPair.
commit b631fc0bc82957e07ad2a18ca1747eced2d6ca6e
Author: David Fifield <david@xxxxxxxxxxxxxxx>
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
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits