tor-commits
Threads by month
- ----- 2025 -----
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
June 2011
- 14 participants
- 716 discussions
commit 8ae82797738a29167cf1c6b1326b20b1794f2997
Author: David Fifield <david(a)bamsoftware.com>
Date: Sat Jun 11 13:45:18 2011 -0700
Use a separate Badge class for UI.
Ported from rtmfp branch.
---
swfcat.as | 162 ++++++++++++++++++++++++++++++++++--------------------------
1 files changed, 92 insertions(+), 70 deletions(-)
diff --git a/swfcat.as b/swfcat.as
index 4aa430b..8d893b2 100644
--- a/swfcat.as
+++ b/swfcat.as
@@ -36,23 +36,16 @@ package
/* TextField …
[View More]for debug output. */
private var output_text:TextField;
- private var fac_addr:Object;
+ /* UI shown when debug is off. */
+ private var badge:Badge;
/* Number of proxy pairs currently connected (up to
MAX_NUM_PROXY_PAIRS). */
private var num_proxy_pairs:int = 0;
- /* Number of proxy pairs ever connected. */
- private var total_proxy_pairs:int = 0;
- public var rate_limit:RateLimit;
+ private var fac_addr:Object;
- /* Badge with a client counter */
- [Embed(source="badge.png")]
- private var BadgeImage:Class;
- private var tot_client_count_tf:TextField;
- private var tot_client_count_fmt:TextFormat;
- private var cur_client_count_tf:TextField;
- private var cur_client_count_fmt:TextFormat;
+ public var rate_limit:RateLimit;
public function puts(s:String):void
{
@@ -60,20 +53,6 @@ package
output_text.scrollV = output_text.maxScrollV;
}
- public function update_client_count():void
- {
- /* Update total client count. */
- if (String(total_proxy_pairs).length == 1)
- tot_client_count_tf.text = "0" + String(total_proxy_pairs);
- else
- tot_client_count_tf.text = String(total_proxy_pairs);
-
- /* Update current client count. */
- cur_client_count_tf.text = "";
- for(var i:Number=0; i<num_proxy_pairs; i++)
- cur_client_count_tf.appendText(".");;
- }
-
public function swfcat()
{
// Absolute positioning.
@@ -87,38 +66,7 @@ package
output_text.backgroundColor = 0x001f0f;
output_text.textColor = 0x44cc44;
- /* Setup client counter for badge. */
- tot_client_count_fmt = new TextFormat();
- tot_client_count_fmt.color = 0xFFFFFF;
- tot_client_count_fmt.align = "center";
- tot_client_count_fmt.font = "courier-new";
- tot_client_count_fmt.bold = true;
- tot_client_count_fmt.size = 10;
- tot_client_count_tf = new TextField();
- tot_client_count_tf.width = 20;
- tot_client_count_tf.height = 17;
- tot_client_count_tf.background = false;
- tot_client_count_tf.defaultTextFormat = tot_client_count_fmt;
- tot_client_count_tf.x=47;
- tot_client_count_tf.y=0;
-
- cur_client_count_fmt = new TextFormat();
- cur_client_count_fmt.color = 0xFFFFFF;
- cur_client_count_fmt.align = "center";
- cur_client_count_fmt.font = "courier-new";
- cur_client_count_fmt.bold = true;
- cur_client_count_fmt.size = 10;
- cur_client_count_tf = new TextField();
- cur_client_count_tf.width = 20;
- cur_client_count_tf.height = 17;
- cur_client_count_tf.background = false;
- cur_client_count_tf.defaultTextFormat = cur_client_count_fmt;
- cur_client_count_tf.x=47;
- cur_client_count_tf.y=6;
-
-
- /* Update the client counter on badge. */
- update_client_count();
+ badge = new Badge();
if (RATE_LIMIT)
rate_limit = new BucketRateLimit(RATE_LIMIT * RATE_LIMIT_HISTORY, RATE_LIMIT_HISTORY);
@@ -138,13 +86,8 @@ package
if (this.loaderInfo.parameters["debug"])
addChild(output_text);
- else {
- addChild(new BadgeImage());
- /* Tried unsuccessfully to add counter to badge. */
- /* For now, need two addChilds :( */
- addChild(tot_client_count_tf);
- addChild(cur_client_count_tf);
- }
+ else
+ addChild(badge);
fac_addr = get_param_addr("facilitator", DEFAULT_FACILITATOR_ADDR);
if (!fac_addr) {
@@ -236,17 +179,13 @@ package
}
num_proxy_pairs++;
- total_proxy_pairs++;
- /* Update the client count on the badge. */
- update_client_count();
+ badge.proxy_begin();
proxy_pair = new ProxyPair(this, client_addr, relay_addr);
proxy_pair.addEventListener(Event.COMPLETE, function(e:Event):void {
proxy_pair.log("Complete.");
-
num_proxy_pairs--;
- /* Update the client count on the badge. */
- update_client_count();
+ badge.proxy_end();
});
proxy_pair.connect();
@@ -272,6 +211,8 @@ package
}
import flash.display.Sprite;
+import flash.text.TextFormat;
+import flash.text.TextField;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IOErrorEvent;
@@ -284,6 +225,87 @@ import flash.utils.clearTimeout;
import flash.utils.getTimer;
import flash.utils.setTimeout;
+class Badge extends flash.display.Sprite
+{
+ /* Number of proxy pairs currently connected. */
+ private var num_proxy_pairs:int = 0;
+ /* Number of proxy pairs ever connected. */
+ private var total_proxy_pairs:int = 0;
+
+ [Embed(source="badge.png")]
+ private var BadgeImage:Class;
+ private var tot_client_count_tf:TextField;
+ private var tot_client_count_fmt:TextFormat;
+ private var cur_client_count_tf:TextField;
+ private var cur_client_count_fmt:TextFormat;
+
+ public function Badge()
+ {
+ /* Setup client counter for badge. */
+ tot_client_count_fmt = new TextFormat();
+ tot_client_count_fmt.color = 0xFFFFFF;
+ tot_client_count_fmt.align = "center";
+ tot_client_count_fmt.font = "courier-new";
+ tot_client_count_fmt.bold = true;
+ tot_client_count_fmt.size = 10;
+ tot_client_count_tf = new TextField();
+ tot_client_count_tf.width = 20;
+ tot_client_count_tf.height = 17;
+ tot_client_count_tf.background = false;
+ tot_client_count_tf.defaultTextFormat = tot_client_count_fmt;
+ tot_client_count_tf.x=47;
+ tot_client_count_tf.y=0;
+
+ cur_client_count_fmt = new TextFormat();
+ cur_client_count_fmt.color = 0xFFFFFF;
+ cur_client_count_fmt.align = "center";
+ cur_client_count_fmt.font = "courier-new";
+ cur_client_count_fmt.bold = true;
+ cur_client_count_fmt.size = 10;
+ cur_client_count_tf = new TextField();
+ cur_client_count_tf.width = 20;
+ cur_client_count_tf.height = 17;
+ cur_client_count_tf.background = false;
+ cur_client_count_tf.defaultTextFormat = cur_client_count_fmt;
+ cur_client_count_tf.x=47;
+ cur_client_count_tf.y=6;
+
+ addChild(new BadgeImage());
+ addChild(tot_client_count_tf);
+ addChild(cur_client_count_tf);
+
+ /* Update the client counter on badge. */
+ update_client_count();
+ }
+
+ public function proxy_begin():void
+ {
+ num_proxy_pairs++;
+ total_proxy_pairs++;
+ update_client_count();
+ }
+
+ public function proxy_end():void
+ {
+ num_proxy_pairs--;
+ update_client_count();
+ }
+
+ private function update_client_count():void
+ {
+ /* Update total client count. */
+ if (String(total_proxy_pairs).length == 1)
+ tot_client_count_tf.text = "0" + String(total_proxy_pairs);
+ else
+ tot_client_count_tf.text = String(total_proxy_pairs);
+
+ /* Update current client count. */
+ cur_client_count_tf.text = "";
+ for(var i:Number = 0; i < num_proxy_pairs; i++)
+ cur_client_count_tf.appendText(".");
+ }
+}
+
class RateLimit
{
public function RateLimit()
[View Less]
1
0
commit a7cdef5eaddee994257579f0b2db01c65164eda4
Author: ellitron <jdellit(a)stanford.edu>
Date: Fri May 27 12:27:00 2011 -0700
Added badge
---
badge_con_counter.png | Bin 0 -> 270 bytes
return_of_the_rtmfpcat.as | 157 +++++++++++++++++++++++++++++++++++++++------
2 files changed, 138 insertions(+), 19 deletions(-)
diff --git a/badge_con_counter.png b/badge_con_counter.png
new file mode 100644
index 0000000..d832e24
Binary files /dev/null and b/badge_con_counter.png …
[View More]differ
diff --git a/return_of_the_rtmfpcat.as b/return_of_the_rtmfpcat.as
index a1d14cc..e512408 100644
--- a/return_of_the_rtmfpcat.as
+++ b/return_of_the_rtmfpcat.as
@@ -54,13 +54,15 @@ package
private static const DEFAULT_CIRCON_TIMEOUT:uint = 4000;
+ private static const DEFAULT_PEER_CON_TIMEOUT:uint = 4000;
+
/* Maximum connections. */
private const DEFAULT_MAXIMUM_RCP_PAIRS:uint = 1;
/* Milliseconds. */
private const FACILITATOR_POLL_INTERVAL:int = 10000;
- private var max_rcp_pairs;
+ private var max_rcp_pairs:uint;
/* TextField for debug output. */
private var output_text:TextField;
@@ -90,19 +92,42 @@ package
/* Number of connected RTMFPConnectionPairs. */
private var rcp_pairs:uint;
+ private var rcp_pairs_total:uint;
private var rtmfp_data_counter:uint;
/* Keep track of facilitator polling timer. */
private var fac_poll_timeo_id:uint;
+ /* Badge with a client counter */
+ [Embed(source="badge_con_counter.png")]
+ private var BadgeImage:Class;
+ private var tot_client_count_tf:TextField;
+ private var tot_client_count_fmt:TextFormat;
+ private var cur_client_count_tf:TextField;
+ private var cur_client_count_fmt:TextFormat;
+
/* Put a string to the screen. */
public function puts(s:String):void
{
output_text.appendText(s + "\n");
output_text.scrollV = output_text.maxScrollV;
}
-
+
+ public function update_client_count():void
+ {
+ /* Update total client count. */
+ if (String(rcp_pairs_total).length == 1)
+ tot_client_count_tf.text = "0" + String(rcp_pairs_total);
+ else
+ tot_client_count_tf.text = String(rcp_pairs_total);
+
+ /* Update current client count. */
+ cur_client_count_tf.text = "";
+ for(var i:Number=0; i<rcp_pairs; i++)
+ cur_client_count_tf.appendText(".");;
+ }
+
public function return_of_the_rtmfpcat()
{
// Absolute positioning.
@@ -115,6 +140,38 @@ package
output_text.background = true;
output_text.backgroundColor = 0x001f0f;
output_text.textColor = 0x44cc44;
+
+ /* Setup client counter for badge. */
+ tot_client_count_fmt = new TextFormat();
+ tot_client_count_fmt.color = 0xFFFFFF;
+ tot_client_count_fmt.align = "center";
+ tot_client_count_fmt.font = "courier-new";
+ tot_client_count_fmt.bold = true;
+ tot_client_count_fmt.size = 10;
+ tot_client_count_tf = new TextField();
+ tot_client_count_tf.width = 20;
+ tot_client_count_tf.height = 17;
+ tot_client_count_tf.background = false;
+ tot_client_count_tf.defaultTextFormat = tot_client_count_fmt;
+ tot_client_count_tf.x=47;
+ tot_client_count_tf.y=0;
+
+ cur_client_count_fmt = new TextFormat();
+ cur_client_count_fmt.color = 0xFFFFFF;
+ cur_client_count_fmt.align = "center";
+ cur_client_count_fmt.font = "courier-new";
+ cur_client_count_fmt.bold = true;
+ cur_client_count_fmt.size = 10;
+ cur_client_count_tf = new TextField();
+ cur_client_count_tf.width = 20;
+ cur_client_count_tf.height = 17;
+ cur_client_count_tf.background = false;
+ cur_client_count_tf.defaultTextFormat = cur_client_count_fmt;
+ cur_client_count_tf.x=47;
+ cur_client_count_tf.y=6;
+
+ /* Update the client counter on badge. */
+ update_client_count();
/* Initialize connection pair count. */
rcp_pairs = 0;
@@ -136,7 +193,16 @@ package
puts("Parameters loaded.");
proxy_mode = (this.loaderInfo.parameters["proxy"] != null);
- addChild(output_text);
+
+ if(this.loaderInfo.parameters["debug"] != null)
+ addChild(output_text);
+
+ addChild(new BadgeImage());
+ /* Tried unsuccessfully to add counter to badge. */
+ /* For now, need two addChilds :( */
+ addChild(tot_client_count_tf);
+ addChild(cur_client_count_tf);
+
fac_spec = this.loaderInfo.parameters["facilitator"];
if (fac_spec) {
@@ -180,6 +246,9 @@ package
else
max_rcp_pairs = DEFAULT_MAXIMUM_RCP_PAIRS;
+ if(this.loaderInfo.parameters["start"])
+ rtmfp_data_counter = this.loaderInfo.parameters["start"];
+
main();
}
@@ -254,8 +323,14 @@ package
var rcp:RTMFPConnectionPair = new RTMFPConnectionPair(circon, tor_addr, output_text);
rcp.addEventListener(Event.CONNECT, rcp_connect_event);
+ rcp.addEventListener(Event.UNLOAD, function (e:Event):void {
+ /* Failed to connect to peer... continue loop. */
+ puts("RTMFPConnectionPair: Timed out connecting to peer!");
+ if(rcp_pairs < max_rcp_pairs)
+ poll_for_id();
+ });
rcp.addEventListener(Event.CLOSE, rcp_close_event);
- rcp.connect(client_id, client_data);
+ rcp.connect(client_id, client_data, DEFAULT_PEER_CON_TIMEOUT);
} else {
/* Need to clear any outstanding timers to ensure
* that only one timer ever runs. */
@@ -277,6 +352,10 @@ package
puts("RTMFPConnectionPair connected");
rcp_pairs++;
+ rcp_pairs_total++;
+
+ /* Update the client count on the badge. */
+ update_client_count();
if(proxy_mode) {
if(rcp_pairs < max_rcp_pairs) {
@@ -304,6 +383,9 @@ package
rcp_pairs--;
+ /* Update the client count on the badge. */
+ update_client_count();
+
/* FIXME: Do I need to unregister the event listeners so
* that the system can garbage collect the rcp object? */
if(proxy_mode) {
@@ -402,6 +484,8 @@ class RTMFPSocket extends EventDispatcher
/* Keeps the state of our connectedness. */
public var connected:Boolean;
+ private var connect_timeo_id:uint;
+
private var output_text:TextField;
/* Put a string to the screen. */
@@ -437,15 +521,26 @@ class RTMFPSocket extends EventDispatcher
send_stream.publish(data);
}
- public function connect(clientID:String, data:String):void
+ private function connect_timeout():void
+ {
+ puts("RTMFPSocket: Timed out connecting to peer");
+ close();
+ /* OK this is not so nice, because I wanted an Event.TIMEOUT event, but flash gives us none such event :( */
+ dispatchEvent(new Event(Event.UNLOAD));
+ }
+
+ public function connect(clientID:String, data:String, timeout:uint):void
{
puts("RTMFPSocket: connecting to peer...");
+ connect_timeo_id = setTimeout(connect_timeout, timeout);
+
this.data = data;
send_stream = new NetStream(circon, NetStream.DIRECT_CONNECTIONS);
var client:Object = new Object();
client.onPeerConnect = function (peer:NetStream):Boolean {
+ clearTimeout(connect_timeo_id);
puts("RTMFPSocket: connected to peer");
connected = true;
dispatchEvent(new Event(Event.CONNECT));
@@ -605,18 +700,48 @@ class RTMFPConnectionPair extends EventDispatcher
this.output_text = output_text;
}
- public function connect(clientID:String, rtmfp_data:String):void
+ public function connect(clientID:String, rtmfp_data:String, timeout:uint):void
{
s_r = new RTMFPSocket(circon, output_text);
s_r.addEventListener(Event.CONNECT, rtmfp_connect_event);
+ s_r.addEventListener(Event.UNLOAD, function (e:Event):void {
+ dispatchEvent(new Event(Event.UNLOAD));
+ });
+ s_r.addEventListener(ProgressEvent.SOCKET_DATA, function (e:ProgressEvent):void {
+ /* It's possible that we receive data before we're connected
+ * to the tor-side of the connection. In this case we want
+ * to buffer the data. */
+ if(!s_t.connected) {
+ puts("MASSIVE ATTACK!");
+ } else {
+ var bytes:ByteArray = new ByteArray();
+ s_r.readBytes(bytes, 0, e.bytesLoaded);
+ puts("RTMFPConnectionPair: RTMFP: read " + bytes.length + " bytes.");
+ s_t.writeBytes(bytes);
+ }
+ });
s_r.addEventListener(Event.CLOSE, rtmfp_close_event);
- s_r.connect(clientID, rtmfp_data);
+ s_r.connect(clientID, rtmfp_data, timeout);
}
public function listen(rtmfp_data:String):void
{
s_r = new RTMFPSocket(circon, output_text);
s_r.addEventListener(Event.CONNECT, rtmfp_connect_event);
+ s_r.addEventListener(ProgressEvent.SOCKET_DATA, function (e:ProgressEvent):void {
+ /* It's possible that we receive data before we're connected
+ * to the tor-side of the connection. In this case we want
+ * to buffer the data. */
+ if(!s_t.connected) {
+ puts("MASSIVE ATTACK!");
+ } else {
+ var bytes:ByteArray = new ByteArray();
+ s_r.readBytes(bytes, 0, e.bytesLoaded);
+ puts("RTMFPConnectionPair: RTMFP: read " + bytes.length + " bytes.");
+ s_t.writeBytes(bytes);
+ }
+ });
+
s_r.addEventListener(Event.CLOSE, rtmfp_close_event);
s_r.listen(rtmfp_data);
}
@@ -630,18 +755,6 @@ class RTMFPConnectionPair extends EventDispatcher
s_t = new Socket();
s_t.addEventListener(Event.CONNECT, function (e:Event):void {
puts("RTMFPConnectionPair: Tor: connected to " + tor_addr.host + ":" + tor_addr.port + ".");
- s_r.addEventListener(ProgressEvent.SOCKET_DATA, function (e:ProgressEvent):void {
- var bytes:ByteArray = new ByteArray();
- s_r.readBytes(bytes, 0, e.bytesLoaded);
- puts("RTMFPConnectionPair: RTMFP: read " + bytes.length + " bytes.");
- s_t.writeBytes(bytes);
- });
- s_t.addEventListener(ProgressEvent.SOCKET_DATA, function (e:ProgressEvent):void {
- var bytes:ByteArray = new ByteArray();
- s_t.readBytes(bytes, 0, e.bytesLoaded);
- puts("RTMFPConnectionPair: Tor: read " + bytes.length + " bytes.");
- s_r.writeBytes(bytes);
- });
dispatchEvent(new Event(Event.CONNECT));
});
s_t.addEventListener(Event.CLOSE, function (e:Event):void {
@@ -652,6 +765,12 @@ class RTMFPConnectionPair extends EventDispatcher
s_r.close();
dispatchEvent(new Event(Event.CLOSE));
});
+ s_t.addEventListener(ProgressEvent.SOCKET_DATA, function (e:ProgressEvent):void {
+ var bytes:ByteArray = new ByteArray();
+ s_t.readBytes(bytes, 0, e.bytesLoaded);
+ puts("RTMFPConnectionPair: Tor: read " + bytes.length + " bytes.");
+ s_r.writeBytes(bytes);
+ });
s_t.addEventListener(IOErrorEvent.IO_ERROR, function (e:IOErrorEvent):void {
puts("RTMFPConnectionPair: Tor: I/O error: " + e.text + ".");
});
[View Less]
1
0
commit 781f10234c6a11af9a781b08df8dedf2a9bdac8f
Author: Nate Hardison <nate(a)rescomp-09-154551.stanford.edu>
Date: Thu Jun 2 20:20:43 2011 -0700
Incorporated badge into rtmfpcat
---
rtmfpcat.as | 150 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 137 insertions(+), 13 deletions(-)
diff --git a/rtmfpcat.as b/rtmfpcat.as
index 224fe56..37701e8 100644
--- a/rtmfpcat.as
+++ b/rtmfpcat.as
@@ -50,47 +50,62 @@ package
private var …
[View More]proxy_pairs:Array;
+ private var debug_mode:Boolean;
private var proxy_mode:Boolean;
/* TextField for debug output. */
private var output_text:TextField;
+
+ /* Badge for display */
+ private var badge:InternetFreedomBadge;
private var fac_addr:Object;
private var relay_addr:Object;
public function rtmfpcat()
{
+ proxy_mode = false;
+ debug_mode = false;
+
// Absolute positioning.
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
-
- output_text = new TextField();
- output_text.width = stage.stageWidth;
- output_text.height = stage.stageHeight;
- output_text.background = true;
- output_text.backgroundColor = 0x001f0f;
- output_text.textColor = 0x44cc44;
- addChild(output_text);
- puts("Starting.");
// Wait until the query string parameters are loaded.
this.loaderInfo.addEventListener(Event.COMPLETE, loaderinfo_complete);
}
public function puts(s:String):void
{
- output_text.appendText(s + "\n");
- output_text.scrollV = output_text.maxScrollV;
+ if (output_text != null) {
+ output_text.appendText(s + "\n");
+ output_text.scrollV = output_text.maxScrollV;
+ }
}
private function loaderinfo_complete(e:Event):void
{
var fac_spec:String;
var relay_spec:String;
-
- puts("Parameters loaded.");
+ debug_mode = (this.loaderInfo.parameters["debug"] != null)
proxy_mode = (this.loaderInfo.parameters["proxy"] != null);
+ if (proxy_mode && !debug_mode) {
+ badge = new InternetFreedomBadge(this);
+ badge.display();
+ } else {
+ output_text = new TextField();
+ output_text.width = stage.stageWidth;
+ output_text.height = stage.stageHeight;
+ output_text.background = true;
+ output_text.backgroundColor = 0x001f0f;
+ output_text.textColor = 0x44cc44;
+ addChild(output_text);
+ }
+
+ puts("Starting: parameters loaded.");
+
+ /* TODO: use this to have multiple proxies going at once */
proxy_pairs = new Array();
fac_spec = this.loaderInfo.parameters["facilitator"];
@@ -157,6 +172,9 @@ package
if (!proxy_mode) {
start_proxy_pair();
s_c.send_hello(e.peer);
+ } else if (!debug_mode && badge != null) {
+ badge.total_proxy_pairs++;
+ badge.num_proxy_pairs++;
}
p_p.connect(e.peer, e.stream);
});
@@ -204,6 +222,9 @@ package
p_p.addEventListener(Event.CLOSE, function (e:Event):void {
puts("ProxyPair: connection closed.");
p_p = null;
+ if (proxy_mode && !debug_mode && badge != null) {
+ badge.num_proxy_pairs++;
+ }
establish_facilitator_connection();
});
p_p.listen(s_c.local_stream_name);
@@ -227,3 +248,106 @@ package
}
}
}
+
+import flash.text.TextField;
+import flash.text.TextFormat;
+
+class InternetFreedomBadge {
+
+ private var ui:rtmfpcat;
+
+ private var _num_proxy_pairs:uint;
+ private var _total_proxy_pairs:uint;
+
+ [Embed(source="badge.png")]
+ private var BadgeImage:Class;
+ private var tot_client_count_tf:TextField;
+ private var tot_client_count_fmt:TextFormat;
+ private var cur_client_count_tf:TextField;
+ private var cur_client_count_fmt:TextFormat;
+
+ public function InternetFreedomBadge(ui:rtmfpcat)
+ {
+ this.ui = ui;
+ _num_proxy_pairs = 0;
+ _total_proxy_pairs = 0;
+
+ /* Setup client counter for badge. */
+ tot_client_count_fmt = new TextFormat();
+ tot_client_count_fmt.color = 0xFFFFFF;
+ tot_client_count_fmt.align = "center";
+ tot_client_count_fmt.font = "courier-new";
+ tot_client_count_fmt.bold = true;
+ tot_client_count_fmt.size = 10;
+ tot_client_count_tf = new TextField();
+ tot_client_count_tf.width = 20;
+ tot_client_count_tf.height = 17;
+ tot_client_count_tf.background = false;
+ tot_client_count_tf.defaultTextFormat = tot_client_count_fmt;
+ tot_client_count_tf.x=47;
+ tot_client_count_tf.y=0;
+
+ cur_client_count_fmt = new TextFormat();
+ cur_client_count_fmt.color = 0xFFFFFF;
+ cur_client_count_fmt.align = "center";
+ cur_client_count_fmt.font = "courier-new";
+ cur_client_count_fmt.bold = true;
+ cur_client_count_fmt.size = 10;
+ cur_client_count_tf = new TextField();
+ cur_client_count_tf.width = 20;
+ cur_client_count_tf.height = 17;
+ cur_client_count_tf.background = false;
+ cur_client_count_tf.defaultTextFormat = cur_client_count_fmt;
+ cur_client_count_tf.x=47;
+ cur_client_count_tf.y=6;
+
+ /* Update the client counter on badge. */
+ update_client_count();
+ }
+
+ public function display():void
+ {
+ ui.addChild(new BadgeImage());
+ /* Tried unsuccessfully to add counter to badge. */
+ /* For now, need two addChilds :( */
+ ui.addChild(tot_client_count_tf);
+ ui.addChild(cur_client_count_tf);
+ }
+
+ public function get num_proxy_pairs():uint
+ {
+ return _num_proxy_pairs;
+ }
+
+ public function set num_proxy_pairs(amount:uint):void
+ {
+ _num_proxy_pairs = amount;
+ update_client_count();
+ }
+
+ public function get total_proxy_pairs():uint
+ {
+ return _total_proxy_pairs;
+ }
+
+ public function set total_proxy_pairs(amount:uint):void
+ {
+ _total_proxy_pairs = amount;
+ /* note: doesn't update, so be sure to update this
+ before you update num_proxy_pairs! */
+ }
+
+ private function update_client_count():void
+ {
+ /* Update total client count. */
+ if (String(total_proxy_pairs).length == 1)
+ tot_client_count_tf.text = "0" + String(total_proxy_pairs);
+ else
+ tot_client_count_tf.text = String(total_proxy_pairs);
+
+ /* Update current client count. */
+ cur_client_count_tf.text = "";
+ for(var i:Number = 0; i < num_proxy_pairs; i++)
+ cur_client_count_tf.appendText(".");
+ }
+}
[View Less]
1
0

[flashproxy/master] Using URLLoader in the FacilitatorSocket, Facilitator now speaks true HTTP
by dcf@torproject.org 12 Jun '11
by dcf@torproject.org 12 Jun '11
12 Jun '11
commit fbffb6fce47047c877d8dc4d2a83bcb4ee2926ea
Author: Nate Hardison <nate(a)rescomp-09-154551.stanford.edu>
Date: Thu Jun 2 19:49:49 2011 -0700
Using URLLoader in the FacilitatorSocket, Facilitator now speaks true HTTP
---
facilitator.py | 55 +++++++++++++++++---
rtmfp/FacilitatorSocket.as | 121 ++++++++++++++++++++------------------------
rtmfpcat.as | 19 ++-----
3 files changed, 106 insertions(+), 89 deletions(-)
diff --git a/facilitator.py …
[View More]b/facilitator.py
index c9859db..0ea86a1 100755
--- a/facilitator.py
+++ b/facilitator.py
@@ -10,6 +10,7 @@ import socket
import sys
import threading
import time
+import urllib
DEFAULT_ADDRESS = "0.0.0.0"
DEFAULT_PORT = 9002
@@ -190,31 +191,47 @@ class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
def do_GET(self):
log(u"proxy %s connects" % format_addr(self.client_address))
+ if self.path == "/crossdomain.xml":
+ self.send_crossdomain()
+ return
+
+ client = ""
reg = REGS.fetch()
if reg:
log(u"proxy %s gets %s (now %d)" % (format_addr(self.client_address), unicode(reg), len(REGS)))
- self.request.send(str(reg))
+ client = str(reg)
else:
log(u"proxy %s gets none" % format_addr(self.client_address))
+ client = "Registration list empty"
+
+ response = "client=%s" % urllib.quote(client)
+ self.send_response(200)
+ self.send_header('Content-Type', 'text/html')
+ self.send_header('Content-Length', str(len(response)))
+ self.end_headers()
+ self.wfile.write(response)
def do_POST(self):
- data = self.rfile.readline(1024).strip()
- try:
- vals = cgi.parse_qs(data, False, True)
- except ValueError, e:
- log(u"client %s POST syntax error: %s" % (format_addr(self.client_address), repr(str(e))))
+ data = cgi.FieldStorage(fp = self.rfile, headers = self.headers,
+ environ = {'REQUEST_METHOD' : 'POST',
+ 'CONTENT_TYPE' : self.headers['Content-Type']})
+
+ if self.path == "/crossdomain.xml":
+ self.send_crossdomain()
return
- client_specs = vals.get("client")
- if client_specs is None or len(client_specs) != 1:
+ client_specs = data["client"]
+ if client_specs is None or client_specs.value is None:
log(u"client %s missing \"client\" param" % format_addr(self.client_address))
+ self.send_error(404)
return
- val = client_specs[0]
+ val = client_specs.value
try:
reg = Reg.parse(val, self.client_address[0])
except ValueError, e:
log(u"client %s syntax error in %s: %s" % (format_addr(self.client_address), repr(val), repr(str(e))))
+ self.send_error(404)
return
log(u"client %s regs %s -> %s" % (format_addr(self.client_address), val, unicode(reg)))
@@ -222,10 +239,30 @@ class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
log(u"client %s %s (now %d)" % (format_addr(self.client_address), unicode(reg), len(REGS)))
else:
log(u"client %s %s (already present, now %d)" % (format_addr(self.client_address), unicode(reg), len(REGS)))
+
+ response = ""
+
+ self.send_response(200)
+ self.send_header('Content-Type', 'text/html')
+ self.send_header('Content-Length', str(len(response)))
+ self.send_header('Connection', 'close')
+ self.end_headers()
+ self.wfile.write(response)
def log_message(self, format, *args):
msg = format % args
log(u"message from HTTP handler for %s: %s" % (format_addr(self.client_address), repr(msg)))
+
+ def send_crossdomain(self):
+ crossdomain = """\
+<cross-domain-policy>
+ <allow-access-from domain="*" to-ports="%s"/>
+</cross-domain-policy>\r\n""" % (address[1])
+ self.send_response(200)
+ self.send_header('Content-Type', 'application/xml')
+ self.send_header('Content-Length', str(len(crossdomain)))
+ self.end_headers()
+ self.wfile.write(crossdomain)
REGS = RegSet()
diff --git a/rtmfp/FacilitatorSocket.as b/rtmfp/FacilitatorSocket.as
index e175290..32c8a7d 100644
--- a/rtmfp/FacilitatorSocket.as
+++ b/rtmfp/FacilitatorSocket.as
@@ -1,108 +1,94 @@
package rtmfp
{
- import flash.net.Socket;
import flash.events.Event;
import flash.events.EventDispatcher;
+ import flash.events.HTTPStatusEvent;
import flash.events.IOErrorEvent;
- import flash.events.NetStatusEvent;
- import flash.events.ProgressEvent;
import flash.events.SecurityErrorEvent;
- import flash.utils.clearInterval;
- import flash.utils.setInterval;
+ import flash.net.URLLoader;
+ import flash.net.URLLoaderDataFormat;
+ import flash.net.URLRequest;
+ import flash.net.URLRequestMethod;
+ import flash.net.URLVariables;
+ import flash.system.Security;
import rtmfp.events.FacilitatorSocketEvent;
- [Event(name=FacilitatorSocketEvent.CONNECT_CLOSED, type="com.flashproxy.rtmfp.events.FacilitatorSocketEvent")]
[Event(name=FacilitatorSocketEvent.CONNECT_FAILED, type="com.flashproxy.rtmfp.events.FacilitatorSocketEvent")]
- [Event(name=FacilitatorSocketEvent.CONNECT_SUCCESS, type="com.flashproxy.rtmfp.events.FacilitatorSocketEvent")]
[Event(name=FacilitatorSocketEvent.REGISTRATION_FAILED, type="com.flashproxy.rtmfp.events.FacilitatorSocketEvent")]
[Event(name=FacilitatorSocketEvent.REGISTRATION_RECEIVED, type="com.flashproxy.rtmfp.events.FacilitatorSocketEvent")]
[Event(name=FacilitatorSocketEvent.REGISTRATIONS_EMPTY, type="com.flashproxy.rtmfp.events.FacilitatorSocketEvent")]
public class FacilitatorSocket extends EventDispatcher
{
- private var socket:Socket;
- private var connected:Boolean;
- private var connection_timeout:uint;
+ private var host:String;
+ private var port:uint;
- public function FacilitatorSocket()
- {
- socket = null;
- connected = false;
- }
-
- public function close():void
- {
- connected = false;
- if (socket != null) {
- socket.removeEventListener(Event.CONNECT, on_connect_event);
- socket.removeEventListener(Event.CLOSE, on_close_event);
- socket.removeEventListener(IOErrorEvent.IO_ERROR, on_io_error_event);
- socket.removeEventListener(ProgressEvent.SOCKET_DATA, on_progress_event);
- socket.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, on_security_error_event);
- if (connected) {
- socket.close();
- }
- }
- }
-
- public function connect(host:String, port:uint):void
- {
- if (socket != null || connected) {
- return;
- }
-
- socket = new Socket();
- socket.addEventListener(Event.CONNECT, on_connect_event);
- socket.addEventListener(Event.CLOSE, on_close_event);
- socket.addEventListener(IOErrorEvent.IO_ERROR, on_io_error_event);
- socket.addEventListener(ProgressEvent.SOCKET_DATA, on_progress_event);
- socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, on_security_error_event);
- socket.connect(host, port);
+ public function FacilitatorSocket(host:String, port:uint)
+ {
+ this.host = host;
+ this.port = port;
}
public function get_registration():void
{
- if (!connected) return;
- socket.writeUTFBytes("GET / HTTP/1.0\r\n\r\n");
+ make_request(URLRequestMethod.GET);
}
public function post_registration(registration_data:String):void
- {
- if (!connected) return;
- socket.writeUTFBytes("POST / HTTP/1.0\r\n\r\nclient=" + registration_data + "\r\n");
+ {
+ var data:URLVariables = new URLVariables();
+ data.client = registration_data;
+ make_request(URLRequestMethod.POST, data);
}
private function fail():void
{
- clearInterval(connection_timeout);
dispatchEvent(new FacilitatorSocketEvent(FacilitatorSocketEvent.CONNECT_FAILED));
}
- private function on_close_event(event:Event):void
+ private function make_request(method:String, data:URLVariables = null):void
{
- close();
- dispatchEvent(new FacilitatorSocketEvent(FacilitatorSocketEvent.CONNECT_CLOSED));
+ var request:URLRequest = new URLRequest(url)
+ request.data = data;
+ request.method = method;
+
+ var url_loader:URLLoader = new URLLoader();
+ url_loader = new URLLoader();
+ url_loader.dataFormat = URLLoaderDataFormat.VARIABLES;
+
+ url_loader.addEventListener(Event.COMPLETE, on_complete_event);
+ url_loader.addEventListener(HTTPStatusEvent.HTTP_STATUS, on_http_status_event);
+ url_loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, on_security_error_event);
+ url_loader.addEventListener(IOErrorEvent.IO_ERROR, on_io_error_event);
+
+ url_loader.load(request);
}
- private function on_connect_event(event:Event):void
+ private function on_complete_event(event:Event):void
{
- connected = true;
- dispatchEvent(new FacilitatorSocketEvent(FacilitatorSocketEvent.CONNECT_SUCCESS));
+ try {
+ var client_id:String = event.target.data.client;
+ if (client_id == "Registration list empty") {
+ dispatchEvent(new FacilitatorSocketEvent(FacilitatorSocketEvent.REGISTRATIONS_EMPTY));
+ } else {
+ dispatchEvent(new FacilitatorSocketEvent(FacilitatorSocketEvent.REGISTRATION_RECEIVED, client_id));
+ }
+ } catch (e:Error) {
+ /* error is thrown for POST when we don't care about
+ the response anyways */
+ }
+
+ event.target.close()
}
- private function on_io_error_event(event:IOErrorEvent):void
+ private function on_http_status_event(event:HTTPStatusEvent):void
{
- fail();
+ /* empty for now */
}
- private function on_progress_event(event:ProgressEvent):void
+ private function on_io_error_event(event:IOErrorEvent):void
{
- var client_id:String = socket.readUTFBytes(event.bytesLoaded);
- if (client_id == "Registration list empty") {
- dispatchEvent(new FacilitatorSocketEvent(FacilitatorSocketEvent.REGISTRATIONS_EMPTY));
- } else {
- dispatchEvent(new FacilitatorSocketEvent(FacilitatorSocketEvent.REGISTRATION_RECEIVED, client_id));
- }
+ fail();
}
private function on_security_error_event(event:SecurityErrorEvent):void
@@ -110,6 +96,9 @@ package rtmfp
fail();
}
-
+ private function get url():String
+ {
+ return "http://" + host + ":" + port;
+ }
}
}
\ No newline at end of file
diff --git a/rtmfpcat.as b/rtmfpcat.as
index 713fc45..224fe56 100644
--- a/rtmfpcat.as
+++ b/rtmfpcat.as
@@ -166,23 +166,11 @@ package
private function establish_facilitator_connection():void
{
- s_f = new FacilitatorSocket();
- s_f.addEventListener(FacilitatorSocketEvent.CONNECT_SUCCESS, function (e:Event):void {
- if (proxy_mode) {
- puts("Facilitator: getting registration.");
- s_f.get_registration();
- } else {
- puts("Facilitator: posting registration.");
- s_f.post_registration(s_c.id);
- }
- });
+ 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, DEFAULT_FAC_POLL_INTERVAL);
});
- s_f.addEventListener(FacilitatorSocketEvent.CONNECT_CLOSED, function (e:Event):void {
- puts("Facilitator: connect closed.");
- });
if (proxy_mode) {
s_f.addEventListener(FacilitatorSocketEvent.REGISTRATION_RECEIVED, function (e:FacilitatorSocketEvent):void {
@@ -194,13 +182,16 @@ package
puts("Facilitator: no registrations available.");
setTimeout(establish_facilitator_connection, DEFAULT_FAC_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, DEFAULT_FAC_POLL_INTERVAL);
});
+ puts("Facilitator: posting registration.");
+ s_f.post_registration(s_c.id);
}
- s_f.connect(fac_addr.host, fac_addr.port);
}
private function start_proxy_pair():void
[View Less]
1
0

[flashproxy/master] Adding in David's rate limiting code to rtmfpcat
by dcf@torproject.org 12 Jun '11
by dcf@torproject.org 12 Jun '11
12 Jun '11
commit ab4e90626b6f6a7152c79b2d2aeeae601deb9d64
Author: Nate Hardison <nate(a)rescomp-09-154551.stanford.edu>
Date: Thu Jun 2 13:23:08 2011 -0700
Adding in David's rate limiting code to rtmfpcat
---
rtmfp/ProxyPair.as | 218 +++++++++++++++++++++++++++++++++++++-------
rtmfp/RTMFPSocketClient.as | 5 +-
rtmfpcat.as | 38 +++-----
3 files changed, 202 insertions(+), 59 deletions(-)
diff --git a/rtmfp/ProxyPair.as b/rtmfp/ProxyPair.as
index 42d4b81..…
[View More]fb184cc 100644
--- a/rtmfp/ProxyPair.as
+++ b/rtmfp/ProxyPair.as
@@ -7,6 +7,8 @@ package rtmfp
import flash.events.SecurityErrorEvent;
import flash.net.Socket;
import flash.utils.ByteArray;
+ import flash.utils.clearTimeout;
+ import flash.utils.setTimeout;
import rtmfp.CirrusSocket;
import rtmfp.RTMFPSocket;
@@ -14,20 +16,41 @@ package rtmfp
public class ProxyPair extends EventDispatcher
{
- private var parent:rtmfpcat;
+ private var ui:rtmfpcat;
private var s_r:RTMFPSocket;
private var s_t:Socket;
private var tor_host:String;
private var tor_port:uint;
+
+ private var p2t_schedule:Array;
+ private var t2p_schedule:Array;
+
+ // Bytes per second. Set to undefined to disable limit.
+ public const RATE_LIMIT:Number = 10000;
+ // Seconds.
+ private const RATE_LIMIT_HISTORY:Number = 5.0;
+
+ private var rate_limit:RateLimit;
+
+ // Callback id.
+ private var flush_id:uint;
- public function ProxyPair(parent:rtmfpcat, s_c:CirrusSocket, tor_host:String, tor_port:uint)
+ public function ProxyPair(ui:rtmfpcat, s_c:CirrusSocket, tor_host:String, tor_port:uint)
{
- this.parent = parent;
+ this.ui = ui;
this.tor_host = tor_host;
this.tor_port = tor_port;
+ this.p2t_schedule = new Array();
+ this.t2p_schedule = new Array();
+
+ if (RATE_LIMIT)
+ rate_limit = new BucketRateLimit(RATE_LIMIT * RATE_LIMIT_HISTORY, RATE_LIMIT_HISTORY);
+ else
+ rate_limit = new RateUnlimit();
+
setup_rtmfp_socket(s_c);
setup_tor_socket();
}
@@ -61,65 +84,196 @@ package rtmfp
private function setup_rtmfp_socket(s_c:CirrusSocket):void
{
s_r = new RTMFPSocket(s_c);
- s_r.addEventListener(RTMFPSocketEvent.PLAY_STARTED, function (e:RTMFPSocketEvent):void {
- puts("Play started.");
+ s_r.addEventListener(RTMFPSocketEvent.CONNECT_FAILED, function (e:RTMFPSocketEvent):void {
+ ui.puts("Peering failed.");
});
- s_r.addEventListener(RTMFPSocketEvent.PUBLISH_STARTED, function (e:RTMFPSocketEvent):void {
- puts("Publishing started.");
+ s_r.addEventListener(RTMFPSocketEvent.CONNECT_SUCCESS, function (e:RTMFPSocketEvent):void {
+ ui.puts("Peering success.");
+ s_t.connect(tor_host, tor_port);
});
s_r.addEventListener(RTMFPSocketEvent.PEER_CONNECTED, function (e:RTMFPSocketEvent):void {
- puts("Peer connected.");
+ ui.puts("Peer connected.");
});
s_r.addEventListener(RTMFPSocketEvent.PEER_DISCONNECTED, function (e:RTMFPSocketEvent):void {
- puts("Peer disconnected.");
+ ui.puts("Peer disconnected.");
close();
});
- s_r.addEventListener(RTMFPSocketEvent.CONNECT_SUCCESS, function (e:RTMFPSocketEvent):void {
- puts("Peering success.");
- s_t.connect(tor_host, tor_port);
+ s_r.addEventListener(RTMFPSocketEvent.PLAY_STARTED, function (e:RTMFPSocketEvent):void {
+ ui.puts("Play started.");
});
- s_r.addEventListener(RTMFPSocketEvent.CONNECT_FAILED, function (e:RTMFPSocketEvent):void {
- puts("Peering failed.");
+ s_r.addEventListener(RTMFPSocketEvent.PUBLISH_STARTED, function (e:RTMFPSocketEvent):void {
+ ui.puts("Publishing started.");
});
+ s_r.addEventListener(ProgressEvent.SOCKET_DATA, proxy_to_tor);
}
private function setup_tor_socket():void
{
s_t = new Socket();
s_t.addEventListener(Event.CONNECT, function (e:Event):void {
- puts("Tor: connected to " + tor_host + ":" + tor_port + ".");
- s_t.addEventListener(ProgressEvent.SOCKET_DATA, function (e:ProgressEvent):void {
- var bytes:ByteArray = new ByteArray();
- s_t.readBytes(bytes, 0, e.bytesLoaded);
- puts("RTMFPSocket: Tor: read " + bytes.length + " bytes.");
- s_r.writeBytes(bytes);
- });
- s_r.addEventListener(ProgressEvent.SOCKET_DATA, function (e:ProgressEvent):void {
- var bytes:ByteArray = new ByteArray();
- s_r.readBytes(bytes, 0, e.bytesLoaded);
- puts("RTMFPSocket: RTMFP: read " + bytes.length + " bytes.");
- s_t.writeBytes(bytes);
- });
+ ui.puts("Tor: connected to " + tor_host + ":" + tor_port + ".");
dispatchEvent(new Event(Event.CONNECT));
});
s_t.addEventListener(Event.CLOSE, function (e:Event):void {
- puts("Tor: closed connection.");
+ ui.puts("Tor: closed connection.");
close();
});
s_t.addEventListener(IOErrorEvent.IO_ERROR, function (e:IOErrorEvent):void {
- puts("Tor: I/O error: " + e.text + ".");
+ ui.puts("Tor: I/O error: " + e.text + ".");
close();
});
s_t.addEventListener(SecurityErrorEvent.SECURITY_ERROR, function (e:SecurityErrorEvent):void {
- puts("Tor: security error: " + e.text + ".");
+ ui.puts("Tor: security error: " + e.text + ".");
close();
});
+ s_t.addEventListener(ProgressEvent.SOCKET_DATA, tor_to_proxy);
}
- private function puts(s:String):void
+ private function tor_to_proxy(e:ProgressEvent):void
+ {
+ t2p_schedule.push(e.bytesLoaded);
+ flush();
+ }
+
+ private function proxy_to_tor(e:ProgressEvent):void
{
- parent.puts(s);
+ p2t_schedule.push(e.bytesLoaded);
+ flush();
}
+ /* Send as much data as the rate limit currently allows. */
+ private function flush():void
+ {
+ if (flush_id)
+ clearTimeout(flush_id);
+ flush_id = undefined;
+
+ if (!(s_r.connected && s_t.connected))
+ /* Can't do anything until both sockets are connected. */
+ return;
+
+ while (!rate_limit.is_limited() && (p2t_schedule.length > 0 || t2p_schedule.length > 0)) {
+ var numBytes:uint;
+ var bytes:ByteArray;
+
+ if (p2t_schedule.length > 0) {
+ numBytes = p2t_schedule.shift();
+ bytes = new ByteArray();
+ s_r.readBytes(bytes, 0, numBytes);
+ ui.puts("ProxyPair: RTMFP: read " + bytes.length + " bytes.");
+ s_t.writeBytes(bytes);
+ rate_limit.update(numBytes);
+ }
+ if (t2p_schedule.length > 0) {
+ numBytes = t2p_schedule.shift();
+ bytes = new ByteArray();
+ s_t.readBytes(bytes, 0, numBytes);
+ ui.puts("ProxyPair: Tor: read " + bytes.length + " bytes.");
+ s_r.writeBytes(bytes);
+ rate_limit.update(numBytes);
+ }
+ }
+
+ /* Call again when safe, if necessary. */
+ if (p2t_schedule.length > 0 || t2p_schedule.length > 0)
+ flush_id = setTimeout(flush, rate_limit.when() * 1000);
+ }
+ }
+}
+
+import flash.utils.getTimer;
+
+class RateLimit
+{
+ public function RateLimit()
+ {
+ }
+
+ public function update(n:Number):Boolean
+ {
+ return true;
+ }
+
+ public function when():Number
+ {
+ return 0.0;
+ }
+
+ public function is_limited():Boolean
+ {
+ return false;
+ }
+}
+
+class RateUnlimit extends RateLimit
+{
+ public function RateUnlimit()
+ {
+ }
+
+ public override function update(n:Number):Boolean
+ {
+ return true;
+ }
+
+ public override function when():Number
+ {
+ return 0.0;
+ }
+
+ public override function is_limited():Boolean
+ {
+ return false;
+ }
+}
+
+class BucketRateLimit extends RateLimit
+{
+ private var amount:Number;
+ private var capacity:Number;
+ private var time:Number;
+ private var last_update:uint;
+
+ public function BucketRateLimit(capacity:Number, time:Number)
+ {
+ this.amount = 0.0;
+ /* capacity / time is the rate we are aiming for. */
+ this.capacity = capacity;
+ this.time = time;
+ this.last_update = getTimer();
+ }
+
+ private function age():void
+ {
+ var now:uint;
+ var delta:Number;
+
+ now = getTimer();
+ delta = (now - last_update) / 1000.0;
+ last_update = now;
+
+ amount -= delta * capacity / time;
+ if (amount < 0.0)
+ amount = 0.0;
+ }
+
+ public override function update(n:Number):Boolean
+ {
+ age();
+ amount += n;
+
+ return amount <= capacity;
+ }
+
+ public override function when():Number
+ {
+ age();
+ return (amount - capacity) / (capacity / time);
+ }
+
+ public override function is_limited():Boolean
+ {
+ age();
+ return amount > capacity;
}
}
\ No newline at end of file
diff --git a/rtmfp/RTMFPSocketClient.as b/rtmfp/RTMFPSocketClient.as
index 7469a53..b917bcb 100644
--- a/rtmfp/RTMFPSocketClient.as
+++ b/rtmfp/RTMFPSocketClient.as
@@ -28,9 +28,8 @@ package rtmfp
public function data_available(bytes:ByteArray):void
{
- this._bytes.clear();
- bytes.readBytes(this._bytes);
- dispatchEvent(new ProgressEvent(ProgressEvent.SOCKET_DATA, false, false, this._bytes.bytesAvailable, this._bytes.length));
+ bytes.readBytes(_bytes, _bytes.length, 0);
+ dispatchEvent(new ProgressEvent(ProgressEvent.SOCKET_DATA, false, false, _bytes.bytesAvailable, _bytes.bytesAvailable));
}
public function get connect_acknowledged():Boolean
diff --git a/rtmfpcat.as b/rtmfpcat.as
index 25099dd..2273bc9 100644
--- a/rtmfpcat.as
+++ b/rtmfpcat.as
@@ -6,8 +6,7 @@ package
import flash.text.TextField;
import flash.text.TextFormat;
import flash.events.Event;
- import flash.utils.clearInterval;
- import flash.utils.setInterval;
+ import flash.utils.setTimeout;
import rtmfp.CirrusSocket;
import rtmfp.FacilitatorSocket;
@@ -39,9 +38,8 @@ package
port: 9001
};
- /* Poll facilitator every 3 sec if in proxy mode and haven't found
- anyone to proxy */
- private const DEFAULT_FAC_POLL_INTERVAL:uint = 3000;
+ /* Poll facilitator every 10 sec */
+ private const DEFAULT_FAC_POLL_INTERVAL:uint = 10000;
// Socket to Cirrus server
private var s_c:CirrusSocket;
@@ -54,8 +52,6 @@ package
private var proxy_mode:Boolean;
- private var fac_poll_interval:uint;
-
/* TextField for debug output. */
private var output_text:TextField;
@@ -80,6 +76,12 @@ package
// Wait until the query string parameters are loaded.
this.loaderInfo.addEventListener(Event.COMPLETE, loaderinfo_complete);
}
+
+ public function puts(s:String):void
+ {
+ output_text.appendText(s + "\n");
+ output_text.scrollV = output_text.maxScrollV;
+ }
private function loaderinfo_complete(e:Event):void
{
@@ -133,11 +135,7 @@ package
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) {
- fac_poll_interval = setInterval(establish_facilitator_connection, DEFAULT_FAC_POLL_INTERVAL);
- } else {
- establish_facilitator_connection();
- }
+ establish_facilitator_connection();
});
s_c.addEventListener(CirrusSocketEvent.CONNECT_FAILED, function (e:CirrusSocketEvent):void {
puts("Error: failed to connect to Cirrus.");
@@ -180,6 +178,7 @@ package
});
s_f.addEventListener(FacilitatorSocketEvent.CONNECT_FAILED, function (e:Event):void {
puts("Facilitator: connect failed.");
+ setTimeout(establish_facilitator_connection, DEFAULT_FAC_POLL_INTERVAL);
});
s_f.addEventListener(FacilitatorSocketEvent.CONNECT_CLOSED, function (e:Event):void {
puts("Facilitator: connect closed.");
@@ -188,16 +187,17 @@ package
if (proxy_mode) {
s_f.addEventListener(FacilitatorSocketEvent.REGISTRATION_RECEIVED, function (e:FacilitatorSocketEvent):void {
puts("Facilitator: got registration " + e.client);
- clearInterval(fac_poll_interval);
start_proxy_pair();
s_c.send_hello(e.client);
});
s_f.addEventListener(FacilitatorSocketEvent.REGISTRATIONS_EMPTY, function (e:Event):void {
puts("Facilitator: no registrations available.");
+ setTimeout(establish_facilitator_connection, DEFAULT_FAC_POLL_INTERVAL);
});
} else {
s_f.addEventListener(FacilitatorSocketEvent.REGISTRATION_FAILED, function (e:Event):void {
puts("Facilitator: registration failed.");
+ setTimeout(establish_facilitator_connection, DEFAULT_FAC_POLL_INTERVAL);
});
}
s_f.connect(fac_addr.host, fac_addr.port);
@@ -213,11 +213,7 @@ package
p_p.addEventListener(Event.CLOSE, function (e:Event):void {
puts("ProxyPair: connection closed.");
p_p = null;
- if (proxy_mode) {
- fac_poll_interval = setInterval(establish_facilitator_connection, DEFAULT_FAC_POLL_INTERVAL);
- } else {
- establish_facilitator_connection();
- }
+ establish_facilitator_connection();
});
p_p.listen(s_c.local_stream_name);
}
@@ -238,11 +234,5 @@ package
return addr;
}
-
- public function puts(s:String):void
- {
- output_text.appendText(s + "\n");
- output_text.scrollV = output_text.maxScrollV;
- }
}
}
[View Less]
1
0

[flashproxy/master] Attempted to fix stream disconnection notification, also trying to fix whitespace
by dcf@torproject.org 12 Jun '11
by dcf@torproject.org 12 Jun '11
12 Jun '11
commit 60e2c5afa70435c9f336bf33097717ff24573515
Author: Nate Hardison <nate(a)rescomp-09-154551.stanford.edu>
Date: Thu Jun 2 10:50:09 2011 -0700
Attempted to fix stream disconnection notification, also trying to fix whitespace
---
rtmfp/CirrusSocket.as | 28 +++++++++++++-------------
rtmfp/RTMFPSocket.as | 53 +++++++++++++++++++++++++-----------------------
rtmfpcat.as | 3 ++
3 files changed, 45 insertions(+), 39 deletions(-)
diff --git a/rtmfp/CirrusSocket.…
[View More]as b/rtmfp/CirrusSocket.as
index 9e97c7d..071ac0d 100644
--- a/rtmfp/CirrusSocket.as
+++ b/rtmfp/CirrusSocket.as
@@ -31,10 +31,10 @@ package rtmfp
{
private static const CONNECT_TIMEOUT:uint = 4000; // in milliseconds
- /* We'll append a unique number to the DATA_STREAM_PREFIX for each
+ /* We'll append a unique number to the DATA_STREAM_PREFIX for each
new stream we create so that we have unique streams per player. */
private static const DATA_STREAM_PREFIX:String = "DATA";
- private var data_stream_suffix:uint = 0;
+ private var data_stream_suffix:uint = 0;
/* Connection to the Cirrus rendezvous service */
public var connection:NetConnection;
@@ -94,18 +94,18 @@ package rtmfp
return DATA_STREAM_PREFIX + data_stream_suffix;
}
- /* Sends a hello message to the Flash player with Cirrus ID "id"
- We use this new call protocol outlined here:
- http://forums.adobe.com/thread/780788?tstart=0 */
- public function send_hello(id:String):void
- {
- if (this.connected) {
- connection.call("relay", null, id, local_stream_name);
- } else {
- throw new Error("Cannot send hello: Cirrus socket not connected.");
- }
- }
-
+ /* Sends a hello message to the Flash player with Cirrus ID "id"
+ We use this new call protocol outlined here:
+ http://forums.adobe.com/thread/780788?tstart=0 */
+ public function send_hello(id:String):void
+ {
+ if (this.connected) {
+ connection.call("relay", null, id, local_stream_name);
+ } else {
+ throw new Error("Cannot send hello: Cirrus socket not connected.");
+ }
+ }
+
/*************************** PRIVATE HELPER FUNCTIONS *************************/
private function fail():void
diff --git a/rtmfp/RTMFPSocket.as b/rtmfp/RTMFPSocket.as
index 6e9a45e..bcbee67 100644
--- a/rtmfp/RTMFPSocket.as
+++ b/rtmfp/RTMFPSocket.as
@@ -27,26 +27,28 @@ package rtmfp
[Event(name=RTMFPSocketEvent.PUBLISH_FAILED, type="com.flashproxy.rtmfp.events.RTMFPSocketEvent")]
public class RTMFPSocket extends EventDispatcher
{
- private const CONNECT_TIMEOUT:uint = 10000;
+ private const CONNECT_TIMEOUT:uint = 10000;
private var s_c:CirrusSocket;
- private var recv_stream:NetStream;
+ private var recv_stream:NetStream;
private var send_stream:NetStream;
- private var connect_timeout:int;
+ private var peer_stream:NetStream;
+
+ private var connect_timeout:int;
public function RTMFPSocket(s_c:CirrusSocket)
{
this.s_c = s_c;
recv_stream = null;
- send_stream = null;
- connect_timeout = 0;
+ send_stream = null;
+ connect_timeout = 0;
}
- /* Tears down this RTMFPSocket, closing both its streams.
- To be used when destroying this object. */
- public function close():void
+ /* Tears down this RTMFPSocket, closing both its streams.
+ To be used when destroying this object. */
+ public function close():void
{
if (send_stream != null) {
s_c.connection.removeEventListener(NetStatusEvent.NET_STATUS, on_stream_disconnection_event);
@@ -81,23 +83,23 @@ package rtmfp
RTMFPSocketClient(recv_stream.client).connect_acknowledged);
}
- /* In RTMFP, you open a listening socket by publishing a named
+ /* In RTMFP, you open a listening socket by publishing a named
stream that others can connect to instead of listening on a port.
You register this stream with the Cirrus server via the Cirrus
socket so that it can redirect connection requests for an id/stream
tuple to this socket. */
public function listen(stream:String):void
{
- // apparently streams don't get disconnection events, only the NetConnection
- // object does...bleh.
- s_c.connection.addEventListener(NetStatusEvent.NET_STATUS, on_stream_disconnection_event);
+ // apparently streams don't get disconnection events, only the NetConnection
+ // object does...bleh.
+ s_c.connection.addEventListener(NetStatusEvent.NET_STATUS, on_stream_disconnection_event);
send_stream = new NetStream(s_c.connection, NetStream.DIRECT_CONNECTIONS);
- send_stream.addEventListener(NetStatusEvent.NET_STATUS, on_send_stream_event);
- var client:Object = new Object();
- client.onPeerConnect = on_peer_connect;
- send_stream.client = client;
- send_stream.publish(stream);
+ send_stream.addEventListener(NetStatusEvent.NET_STATUS, on_send_stream_event);
+ var client:Object = new Object();
+ client.onPeerConnect = on_peer_connect;
+ send_stream.client = client;
+ send_stream.publish(stream);
}
public function get peer():String
@@ -113,16 +115,16 @@ package rtmfp
public function readBytes(bytes:ByteArray, offset:uint = 0, length:uint = 0):void
{
- if (recv_stream != null && recv_stream.client != null) {
- recv_stream.client.bytes.readBytes(bytes, offset, length);
- }
+ if (recv_stream != null && recv_stream.client != null) {
+ recv_stream.client.bytes.readBytes(bytes, offset, length);
+ }
}
public function writeBytes(bytes:ByteArray):void
{
if (send_stream != null && peer_connected) {
- send_stream.send(RTMFPSocketClient.DATA_AVAILABLE, bytes);
- }
+ send_stream.send(RTMFPSocketClient.DATA_AVAILABLE, bytes);
+ }
}
/* Listens for acknowledgement of a connection attempt to a
@@ -130,7 +132,7 @@ package rtmfp
private function on_connect_acknowledged(event:Event):void
{
clearTimeout(connect_timeout);
- dispatchEvent(new RTMFPSocketEvent(RTMFPSocketEvent.CONNECT_SUCCESS, recv_stream));
+ dispatchEvent(new RTMFPSocketEvent(RTMFPSocketEvent.CONNECT_SUCCESS, recv_stream));
}
/* If we don't get a connection acknowledgement by the time this
@@ -163,6 +165,7 @@ package rtmfp
return false;
}
+ peer_stream = peer;
peer.send(RTMFPSocketClient.SET_CONNECT_ACKNOWLEDGED);
// need to do this in a timeout so that this function can
@@ -190,10 +193,10 @@ package rtmfp
private function on_stream_disconnection_event(event:NetStatusEvent):void
{
- if (event.info.code == "NetStream.Connect.Closed") {
+ if (event.info.code == "NetStream.Connect.Closed" && event.info.stream === peer_stream) {
dispatchEvent(new RTMFPSocketEvent(RTMFPSocketEvent.PEER_DISCONNECTED));
- //disconnect();
}
}
}
}
+
diff --git a/rtmfpcat.as b/rtmfpcat.as
index 866175e..25099dd 100644
--- a/rtmfpcat.as
+++ b/rtmfpcat.as
@@ -49,6 +49,8 @@ package
private var s_f:FacilitatorSocket;
// Handle local-remote traffic
private var p_p:ProxyPair;
+
+ private var proxy_pairs:Array;
private var proxy_mode:Boolean;
@@ -87,6 +89,7 @@ package
puts("Parameters loaded.");
proxy_mode = (this.loaderInfo.parameters["proxy"] != null);
+ proxy_pairs = new Array();
fac_spec = this.loaderInfo.parameters["facilitator"];
if (fac_spec) {
[View Less]
1
0

[flashproxy/master] New version of rtmfpcat that works with reconnection
by dcf@torproject.org 12 Jun '11
by dcf@torproject.org 12 Jun '11
12 Jun '11
commit 7c4ca7bf575684c35773605e522ee118c1f8f0bf
Author: Nate Hardison <nate(a)rescomp-09-154551.stanford.edu>
Date: Thu Jun 2 03:45:18 2011 -0700
New version of rtmfpcat that works with reconnection
---
Makefile | 2 +-
rtmfp/CirrusSocket.as | 140 +++++++++++++
rtmfp/FacilitatorSocket.as | 115 +++++++++++
rtmfp/ProxyPair.as | 125 ++++++++++++
rtmfp/RTMFPSocket.as | 340 +++++++…
[View More]++++++++-----------------
rtmfp/RTMFPSocketClient.as | 34 ++--
rtmfp/events/CirrusSocketEvent.as | 22 ++
rtmfp/events/FacilitatorSocketEvent.as | 22 ++
rtmfp/events/RTMFPSocketEvent.as | 13 +-
rtmfpcat.as | 240 ++++++++++++-----------
10 files changed, 729 insertions(+), 324 deletions(-)
diff --git a/Makefile b/Makefile
index bc1f8bf..3595385 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
MXMLC ?= mxmlc
-TARGETS = rtmfpcat.swf return_of_the_rtmfpcat.swf
+TARGETS = rtmfpcat.swf
all: $(TARGETS)
diff --git a/rtmfp/CirrusSocket.as b/rtmfp/CirrusSocket.as
new file mode 100644
index 0000000..d9996f2
--- /dev/null
+++ b/rtmfp/CirrusSocket.as
@@ -0,0 +1,140 @@
+/* CirrusSocket abstraction
+ * ------------------------
+ * Manages the NetConnection portion of RTMFP and also handles
+ * the handshake between two Flash players to decide what their
+ * data stream names will be.
+ *
+ * TODO: consider using farNonce/nearNonce instead of sending bytes?
+ */
+
+package rtmfp
+{
+ import flash.events.Event;
+ import flash.events.EventDispatcher;
+ import flash.events.IOErrorEvent;
+ import flash.events.NetStatusEvent;
+ import flash.events.ProgressEvent;
+ import flash.events.SecurityErrorEvent;
+ import flash.net.NetConnection;
+ import flash.utils.clearInterval;
+ import flash.utils.setInterval;
+
+ import rtmfp.RTMFPSocket;
+ import rtmfp.events.CirrusSocketEvent;
+ import rtmfp.events.RTMFPSocketEvent;
+
+ [Event(name=CirrusSocketEvent.CONNECT_CLOSED, type="com.flashproxy.rtmfp.events.CirrusSocketEvent")]
+ [Event(name=CirrusSocketEvent.CONNECT_FAILED, type="com.flashproxy.rtmfp.events.CirrusSocketEvent")]
+ [Event(name=CirrusSocketEvent.CONNECT_SUCCESS, type="com.flashproxy.rtmfp.events.CirrusSocketEvent")]
+ [Event(name=CirrusSocketEvent.HELLO_RECEIVED, type="com.flashproxy.rtmfp.events.CirrusSocketEvent")]
+ public class CirrusSocket extends EventDispatcher
+ {
+ private static const CONNECT_TIMEOUT:uint = 4000; // in milliseconds
+
+ /* We'll append a unique number to the DATA_STREAM_PREFIX for each
+ new stream we create so that we have unique streams per player. */
+ private static const DATA_STREAM_PREFIX:String = "DATA";
+ private var data_stream_suffix:uint = 0;
+
+ /* Connection to the Cirrus rendezvous service */
+ public var connection:NetConnection;
+
+ /* Timeouts */
+ private var connect_timeout:int;
+ private var hello_timeout:int;
+
+ public function CirrusSocket()
+ {
+ connection = new NetConnection();
+ connection.addEventListener(NetStatusEvent.NET_STATUS, on_net_status_event);
+ connection.addEventListener(IOErrorEvent.IO_ERROR, on_io_error_event);
+ connection.addEventListener(SecurityErrorEvent.SECURITY_ERROR, on_security_error_event);
+ var client:Object = new Object();
+ client.onRelay = on_hello;
+ connection.client = client;
+ }
+
+ public function connect(addr:String, key:String):void
+ {
+ if (!this.connected) {
+ connect_timeout = setInterval(fail, CONNECT_TIMEOUT);
+ connection.connect(addr, key);
+ } else {
+ throw new Error("Cannot connect Cirrus socket: already connected.");
+ }
+ }
+
+ public function close():void
+ {
+ if (this.connected) {
+ connection.close();
+ } else {
+ throw new Error("Cannot close Cirrus socket: not connected.");
+ }
+ }
+
+ public function get connected():Boolean
+ {
+ return (connection != null && connection.connected);
+ }
+
+ public function get id():String
+ {
+ if (this.connected) {
+ return connection.nearID;
+ }
+
+ return null;
+ }
+
+ public function get local_stream_name():String
+ {
+ return DATA_STREAM_PREFIX + data_stream_suffix;
+ }
+
+ /* Sends a hello message to the Flash player with Cirrus ID "id"
+ We use this new call protocol outlined here:
+ http://forums.adobe.com/thread/780788?tstart=0 */
+ public function send_hello(id:String):void
+ {
+ if (this.connected) {
+ connection.call("relay", null, id, local_stream_name);
+ } else {
+ throw new Error("Cannot send hello: Cirrus socket not connected.");
+ }
+ }
+
+/*************************** PRIVATE HELPER FUNCTIONS *************************/
+
+ private function fail():void
+ {
+ clearInterval(connect_timeout);
+ dispatchEvent(new CirrusSocketEvent(CirrusSocketEvent.CONNECT_FAILED));
+ }
+
+ private function on_hello(peer:String, ...args):void
+ {
+ var stream:String = args[0];
+ dispatchEvent(new CirrusSocketEvent(CirrusSocketEvent.HELLO_RECEIVED, peer, stream));
+ data_stream_suffix++;
+ }
+
+ private function on_io_error_event(event:IOErrorEvent):void
+ {
+ fail();
+ }
+
+ private function on_net_status_event(event:NetStatusEvent):void
+ {
+ if (event.info.code == "NetConnection.Connect.Success") {
+ clearInterval(connect_timeout);
+ dispatchEvent(new CirrusSocketEvent(CirrusSocketEvent.CONNECT_SUCCESS));
+ }
+ }
+
+ private function on_security_error_event(event:SecurityErrorEvent):void
+ {
+ fail();
+ }
+ }
+}
diff --git a/rtmfp/FacilitatorSocket.as b/rtmfp/FacilitatorSocket.as
new file mode 100644
index 0000000..e175290
--- /dev/null
+++ b/rtmfp/FacilitatorSocket.as
@@ -0,0 +1,115 @@
+package rtmfp
+{
+ import flash.net.Socket;
+ import flash.events.Event;
+ import flash.events.EventDispatcher;
+ import flash.events.IOErrorEvent;
+ import flash.events.NetStatusEvent;
+ import flash.events.ProgressEvent;
+ import flash.events.SecurityErrorEvent;
+ import flash.utils.clearInterval;
+ import flash.utils.setInterval;
+
+ import rtmfp.events.FacilitatorSocketEvent;
+
+ [Event(name=FacilitatorSocketEvent.CONNECT_CLOSED, type="com.flashproxy.rtmfp.events.FacilitatorSocketEvent")]
+ [Event(name=FacilitatorSocketEvent.CONNECT_FAILED, type="com.flashproxy.rtmfp.events.FacilitatorSocketEvent")]
+ [Event(name=FacilitatorSocketEvent.CONNECT_SUCCESS, type="com.flashproxy.rtmfp.events.FacilitatorSocketEvent")]
+ [Event(name=FacilitatorSocketEvent.REGISTRATION_FAILED, type="com.flashproxy.rtmfp.events.FacilitatorSocketEvent")]
+ [Event(name=FacilitatorSocketEvent.REGISTRATION_RECEIVED, type="com.flashproxy.rtmfp.events.FacilitatorSocketEvent")]
+ [Event(name=FacilitatorSocketEvent.REGISTRATIONS_EMPTY, type="com.flashproxy.rtmfp.events.FacilitatorSocketEvent")]
+ public class FacilitatorSocket extends EventDispatcher
+ {
+ private var socket:Socket;
+ private var connected:Boolean;
+ private var connection_timeout:uint;
+
+ public function FacilitatorSocket()
+ {
+ socket = null;
+ connected = false;
+ }
+
+ public function close():void
+ {
+ connected = false;
+ if (socket != null) {
+ socket.removeEventListener(Event.CONNECT, on_connect_event);
+ socket.removeEventListener(Event.CLOSE, on_close_event);
+ socket.removeEventListener(IOErrorEvent.IO_ERROR, on_io_error_event);
+ socket.removeEventListener(ProgressEvent.SOCKET_DATA, on_progress_event);
+ socket.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, on_security_error_event);
+ if (connected) {
+ socket.close();
+ }
+ }
+ }
+
+ public function connect(host:String, port:uint):void
+ {
+ if (socket != null || connected) {
+ return;
+ }
+
+ socket = new Socket();
+ socket.addEventListener(Event.CONNECT, on_connect_event);
+ socket.addEventListener(Event.CLOSE, on_close_event);
+ socket.addEventListener(IOErrorEvent.IO_ERROR, on_io_error_event);
+ socket.addEventListener(ProgressEvent.SOCKET_DATA, on_progress_event);
+ socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, on_security_error_event);
+ socket.connect(host, port);
+ }
+
+ public function get_registration():void
+ {
+ if (!connected) return;
+ socket.writeUTFBytes("GET / HTTP/1.0\r\n\r\n");
+ }
+
+ public function post_registration(registration_data:String):void
+ {
+ if (!connected) return;
+ socket.writeUTFBytes("POST / HTTP/1.0\r\n\r\nclient=" + registration_data + "\r\n");
+ }
+
+ private function fail():void
+ {
+ clearInterval(connection_timeout);
+ dispatchEvent(new FacilitatorSocketEvent(FacilitatorSocketEvent.CONNECT_FAILED));
+ }
+
+ private function on_close_event(event:Event):void
+ {
+ close();
+ dispatchEvent(new FacilitatorSocketEvent(FacilitatorSocketEvent.CONNECT_CLOSED));
+ }
+
+ private function on_connect_event(event:Event):void
+ {
+ connected = true;
+ dispatchEvent(new FacilitatorSocketEvent(FacilitatorSocketEvent.CONNECT_SUCCESS));
+ }
+
+ private function on_io_error_event(event:IOErrorEvent):void
+ {
+ fail();
+ }
+
+ private function on_progress_event(event:ProgressEvent):void
+ {
+ var client_id:String = socket.readUTFBytes(event.bytesLoaded);
+ if (client_id == "Registration list empty") {
+ dispatchEvent(new FacilitatorSocketEvent(FacilitatorSocketEvent.REGISTRATIONS_EMPTY));
+ } else {
+ dispatchEvent(new FacilitatorSocketEvent(FacilitatorSocketEvent.REGISTRATION_RECEIVED, client_id));
+ }
+ }
+
+ private function on_security_error_event(event:SecurityErrorEvent):void
+ {
+ fail();
+ }
+
+
+ }
+}
\ No newline at end of file
diff --git a/rtmfp/ProxyPair.as b/rtmfp/ProxyPair.as
new file mode 100644
index 0000000..42d4b81
--- /dev/null
+++ b/rtmfp/ProxyPair.as
@@ -0,0 +1,125 @@
+package rtmfp
+{
+ import flash.events.Event;
+ import flash.events.EventDispatcher;
+ import flash.events.IOErrorEvent;
+ import flash.events.ProgressEvent;
+ import flash.events.SecurityErrorEvent;
+ import flash.net.Socket;
+ import flash.utils.ByteArray;
+
+ import rtmfp.CirrusSocket;
+ import rtmfp.RTMFPSocket;
+ import rtmfp.events.RTMFPSocketEvent;
+
+ public class ProxyPair extends EventDispatcher
+ {
+ private var parent:rtmfpcat;
+
+ private var s_r:RTMFPSocket;
+ private var s_t:Socket;
+
+ private var tor_host:String;
+ private var tor_port:uint;
+
+ public function ProxyPair(parent:rtmfpcat, s_c:CirrusSocket, tor_host:String, tor_port:uint)
+ {
+ this.parent = parent;
+ this.tor_host = tor_host;
+ this.tor_port = tor_port;
+
+ setup_rtmfp_socket(s_c);
+ setup_tor_socket();
+ }
+
+ public function close():void
+ {
+ if (s_r.connected) {
+ s_r.close();
+ }
+ if (s_t.connected) {
+ s_t.close();
+ }
+ dispatchEvent(new Event(Event.CLOSE));
+ }
+
+ public function connect(peer:String, stream:String):void
+ {
+ s_r.connect(peer, stream);
+ }
+
+ public function get connected():Boolean
+ {
+ return (s_r.connected && s_t.connected);
+ }
+
+ public function listen(stream:String):void
+ {
+ s_r.listen(stream);
+ }
+
+ private function setup_rtmfp_socket(s_c:CirrusSocket):void
+ {
+ s_r = new RTMFPSocket(s_c);
+ s_r.addEventListener(RTMFPSocketEvent.PLAY_STARTED, function (e:RTMFPSocketEvent):void {
+ puts("Play started.");
+ });
+ s_r.addEventListener(RTMFPSocketEvent.PUBLISH_STARTED, function (e:RTMFPSocketEvent):void {
+ puts("Publishing started.");
+ });
+ s_r.addEventListener(RTMFPSocketEvent.PEER_CONNECTED, function (e:RTMFPSocketEvent):void {
+ puts("Peer connected.");
+ });
+ s_r.addEventListener(RTMFPSocketEvent.PEER_DISCONNECTED, function (e:RTMFPSocketEvent):void {
+ puts("Peer disconnected.");
+ close();
+ });
+ s_r.addEventListener(RTMFPSocketEvent.CONNECT_SUCCESS, function (e:RTMFPSocketEvent):void {
+ puts("Peering success.");
+ s_t.connect(tor_host, tor_port);
+ });
+ s_r.addEventListener(RTMFPSocketEvent.CONNECT_FAILED, function (e:RTMFPSocketEvent):void {
+ puts("Peering failed.");
+ });
+ }
+
+ private function setup_tor_socket():void
+ {
+ s_t = new Socket();
+ s_t.addEventListener(Event.CONNECT, function (e:Event):void {
+ puts("Tor: connected to " + tor_host + ":" + tor_port + ".");
+ s_t.addEventListener(ProgressEvent.SOCKET_DATA, function (e:ProgressEvent):void {
+ var bytes:ByteArray = new ByteArray();
+ s_t.readBytes(bytes, 0, e.bytesLoaded);
+ puts("RTMFPSocket: Tor: read " + bytes.length + " bytes.");
+ s_r.writeBytes(bytes);
+ });
+ s_r.addEventListener(ProgressEvent.SOCKET_DATA, function (e:ProgressEvent):void {
+ var bytes:ByteArray = new ByteArray();
+ s_r.readBytes(bytes, 0, e.bytesLoaded);
+ puts("RTMFPSocket: RTMFP: read " + bytes.length + " bytes.");
+ s_t.writeBytes(bytes);
+ });
+ dispatchEvent(new Event(Event.CONNECT));
+ });
+ s_t.addEventListener(Event.CLOSE, function (e:Event):void {
+ puts("Tor: closed connection.");
+ close();
+ });
+ s_t.addEventListener(IOErrorEvent.IO_ERROR, function (e:IOErrorEvent):void {
+ puts("Tor: I/O error: " + e.text + ".");
+ close();
+ });
+ s_t.addEventListener(SecurityErrorEvent.SECURITY_ERROR, function (e:SecurityErrorEvent):void {
+ puts("Tor: security error: " + e.text + ".");
+ close();
+ });
+ }
+
+ private function puts(s:String):void
+ {
+ parent.puts(s);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/rtmfp/RTMFPSocket.as b/rtmfp/RTMFPSocket.as
index d524699..783a0e0 100644
--- a/rtmfp/RTMFPSocket.as
+++ b/rtmfp/RTMFPSocket.as
@@ -1,13 +1,3 @@
-/* RTMFPSocket abstraction
- * Author: Nate Hardison, May 2011
- *
- * This code is heavily based off of BelugaFile, an open-source
- * Air file-transfer application written by Nicholas Bliyk.
- * Website: http://www.belugafile.com/
- * Source: http://code.google.com/p/belugafile/
- *
- */
-
package rtmfp
{
import flash.events.Event;
@@ -19,213 +9,205 @@ package rtmfp
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.utils.ByteArray;
- import flash.utils.clearInterval;
- import flash.utils.setInterval;
+ import flash.utils.clearTimeout;
import flash.utils.setTimeout;
-
+
+ import rtmfp.CirrusSocket;
import rtmfp.RTMFPSocketClient;
+ import rtmfp.events.CirrusSocketEvent;
import rtmfp.events.RTMFPSocketEvent;
-
- [Event(name="connectSuccess", type="com.jscat.rtmfp.events.RTMFPSocketEvent")]
- [Event(name="connectFail", type="com.jscat.rtmfp.events.RTMFPSocketEvent")]
- [Event(name="publishStart", type="com.jscat.rtmfp.events.RTMFPSocketEvent")]
- [Event(name="peerConnected", type="com.jscat.rtmfp.events.RTMFPSocketEvent")]
- [Event(name="peeringSuccess", type="com.jscat.rtmfp.events.RTMFPSocketEvent")]
- [Event(name="peeringFail", type="com.jscat.rtmfp.events.RTMFPSocketEvent")]
- [Event(name="peerDisconnected", type="com.jscat.rtmfp.events.RTMFPSocketEvent")]
+
+ [Event(name=RTMFPSocketEvent.CONNECT_FAILED, type="com.flashproxy.rtmfp.events.RTMFPSocketEvent")]
+ [Event(name=RTMFPSocketEvent.CONNECT_CLOSED, type="com.flashproxy.rtmfp.events.RTMFPSocketEvent")]
+ [Event(name=RTMFPSocketEvent.CONNECT_SUCCESS, type="com.flashproxy.rtmfp.events.RTMFPSocketEvent")]
+ [Event(name=RTMFPSocketEvent.PEER_CONNECTED, type="com.flashproxy.rtmfp.events.RTMFPSocketEvent")]
+ [Event(name=RTMFPSocketEvent.PEER_DISCONNECTED, type="com.flashproxy.rtmfp.events.RTMFPSocketEvent")]
+ [Event(name=RTMFPSocketEvent.PLAY_STARTED, type="com.flashproxy.rtmfp.events.RTMFPSocketEvent")]
+ [Event(name=RTMFPSocketEvent.PUBLISH_STARTED, type="com.flashproxy.rtmfp.events.RTMFPSocketEvent")]
+ [Event(name=RTMFPSocketEvent.PUBLISH_FAILED, type="com.flashproxy.rtmfp.events.RTMFPSocketEvent")]
public class RTMFPSocket extends EventDispatcher
- {
- /* The name of the "media" to pass between peers */
- private static const DATA:String = "data";
- private static const DEFAULT_CIRRUS_ADDRESS:String = "rtmfp://p2p.rtmfp.net";
- private static const DEFAULT_CIRRUS_KEY:String = RTMFP::CIRRUS_KEY;
- private static const DEFAULT_CONNECT_TIMEOUT:uint = 4000;
-
- /* Connection to the Cirrus rendezvous service */
- private var connection:NetConnection;
-
- /* ID of the peer to connect to */
- private var peerID:String;
-
- /* Data streams to be established with peer */
- private var sendStream:NetStream;
- private var recvStream:NetStream;
-
- /* Timeouts */
- private var connectionTimeout:int;
- private var peerConnectTimeout:uint;
-
- public function RTMFPSocket(){}
-
- public function connect(addr:String = DEFAULT_CIRRUS_ADDRESS, key:String = DEFAULT_CIRRUS_KEY):void
- {
- connection = new NetConnection();
- connection.addEventListener(NetStatusEvent.NET_STATUS, onNetStatusEvent);
- connection.addEventListener(IOErrorEvent.IO_ERROR, onIOErrorEvent);
- connection.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityErrorEvent);
- connection.connect(addr + "/" + key);
- connectionTimeout = setInterval(fail, DEFAULT_CONNECT_TIMEOUT);
- }
-
- public function close():void
- {
- connection.close();
- }
-
- public function get id():String
- {
- if (connection != null && connection.connected) {
- return connection.nearID;
+ {
+ private const CONNECT_TIMEOUT:uint = 10000;
+
+ private var s_c:CirrusSocket;
+
+ private var recv_stream:NetStream;
+ private var send_stream:NetStream;
+
+ private var connect_timeout:int;
+
+ public function RTMFPSocket(s_c:CirrusSocket)
+ {
+ this.s_c = s_c;
+ recv_stream = null;
+ send_stream = null;
+ connect_timeout = 0;
+ }
+
+ /* Tears down this RTMFPSocket, closing both its streams.
+ To be used when destroying this object. If you just want
+ to disconnect from a client, call disconnect() below */
+ public function close():void
+ {
+ if (send_stream != null) {
+ s_c.connection.removeEventListener(NetStatusEvent.NET_STATUS, on_stream_disconnection_event);
+ send_stream.close();
+ }
+
+ if (recv_stream != null) {
+ recv_stream.close();
}
-
- return null;
- }
-
- public function get connected():Boolean
- {
- return (connection != null && connection.connected);
}
- public function readBytes(bytes:ByteArray):void
+ /* In RTMFP, you connect to a remote socket by requesting to
+ "play" the data being published on a named stream by the
+ host identified by id. The connection request goes through
+ the Cirrus server which handles the mapping from id/stream
+ to IP/port and any necessary NAT traversal. */
+ public function connect(id:String, stream:String):void
{
- recvStream.client.bytes.readBytes(bytes);
- }
-
- public function writeBytes(bytes:ByteArray):void
+ recv_stream = new NetStream(s_c.connection, id);
+ var client:RTMFPSocketClient = new RTMFPSocketClient();
+ client.addEventListener(ProgressEvent.SOCKET_DATA, on_data_available, false, 0, true);
+ client.addEventListener(RTMFPSocketClient.CONNECT_ACKNOWLEDGED, on_connect_acknowledged, false, 0, true);
+ recv_stream.client = client;
+ recv_stream.addEventListener(NetStatusEvent.NET_STATUS, on_recv_stream_event);
+ recv_stream.play(stream);
+ connect_timeout = setTimeout(on_connect_timeout, CONNECT_TIMEOUT, recv_stream);
+ }
+
+ public function get connected():Boolean
{
- sendStream.send("dataAvailable", bytes);
- }
-
+ return (recv_stream != null && recv_stream.client != null &&
+ RTMFPSocketClient(recv_stream.client).connect_acknowledged);
+ }
+
+ public function disconnect():void
+ {
+ if (recv_stream != null) {
+ if (recv_stream.client != null) {
+ recv_stream.client.removeEventListener(ProgressEvent.SOCKET_DATA, on_data_available);
+ recv_stream.client.removeEventListener(RTMFPSocketClient.CONNECT_ACKNOWLEDGED, on_connect_acknowledged);
+ }
+ recv_stream.removeEventListener(NetStatusEvent.NET_STATUS, on_recv_stream_event);
+ recv_stream.close();
+ recv_stream = null;
+ }
+ }
+
+ /* In RTMFP, you open a listening socket by publishing a named
+ stream that others can connect to instead of listening on a port.
+ You register this stream with the Cirrus server via the Cirrus
+ socket so that it can redirect connection requests for an id/stream
+ tuple to this socket. */
+ public function listen(stream:String):void
+ {
+ // apparently streams don't get disconnection events, only the NetConnection
+ // object does...bleh.
+ s_c.connection.addEventListener(NetStatusEvent.NET_STATUS, on_stream_disconnection_event);
+
+ send_stream = new NetStream(s_c.connection, NetStream.DIRECT_CONNECTIONS);
+ send_stream.addEventListener(NetStatusEvent.NET_STATUS, on_send_stream_event);
+ var client:Object = new Object();
+ client.onPeerConnect = on_peer_connect;
+ send_stream.client = client;
+ send_stream.publish(stream);
+ }
+
public function get peer():String
{
- return this.peerID;
+ if (!connected) return null;
+ return recv_stream.farID;
}
-
- public function set peer(peerID:String):void
- {
- if (peerID == null || peerID.length == 0) {
- throw new Error("Peer ID is null/empty.")
- } else if (peerID == connection.nearID) {
- throw new Error("Peer ID cannot be the same as our ID.");
- } else if (this.peerID == peerID) {
- throw new Error("Already connected to peer " + peerID + ".");
- } else if (this.recvStream != null) {
- throw new Error("Cannot connect to a second peer.");
- }
-
- this.peerID = peerID;
-
- recvStream = new NetStream(connection, peerID);
- var client:RTMFPSocketClient = new RTMFPSocketClient();
- client.addEventListener(ProgressEvent.SOCKET_DATA, onDataAvailable, false, 0, true);
- client.addEventListener(RTMFPSocketClient.PEER_CONNECT_ACKNOWLEDGED, onPeerConnectAcknowledged, false, 0, true);
- recvStream.client = client;
- recvStream.addEventListener(NetStatusEvent.NET_STATUS, onRecvStreamEvent);
- recvStream.play(DATA);
- setTimeout(onPeerConnectTimeout, peerConnectTimeout, recvStream);
- }
-
- private function startPublishStream():void
+
+ public function get peer_connected():Boolean
{
- sendStream = new NetStream(connection, NetStream.DIRECT_CONNECTIONS);
- sendStream.addEventListener(NetStatusEvent.NET_STATUS, onSendStreamEvent);
- var o:Object = new Object();
- o.onPeerConnect = onPeerConnect;
- sendStream.client = o;
- sendStream.publish(DATA);
+ return send_stream.peerStreams.length > 0;
}
-
- private function fail():void
+
+ public function readBytes(bytes:ByteArray, offset:uint = 0, length:uint = 0):void
{
- clearInterval(connectionTimeout);
- dispatchEvent(new RTMFPSocketEvent(RTMFPSocketEvent.CONNECT_FAIL));
+ if (recv_stream != null && recv_stream.client != null) {
+ recv_stream.client.bytes.readBytes(bytes, offset, length);
+ }
}
- private function onDataAvailable(event:ProgressEvent):void
- {
- dispatchEvent(event);
- }
- private function onIOErrorEvent(event:IOErrorEvent):void
+ public function writeBytes(bytes:ByteArray):void
{
- fail();
+ if (send_stream != null && peer_connected) {
+ send_stream.send(RTMFPSocketClient.DATA_AVAILABLE, bytes);
+ }
}
-
- private function onNetStatusEvent(event:NetStatusEvent):void
+
+ /* Listens for acknowledgement of a connection attempt to a
+ remote peer. */
+ private function on_connect_acknowledged(event:Event):void
{
- switch (event.info.code) {
- case "NetConnection.Connect.Success" :
- clearInterval(connectionTimeout);
- startPublishStream();
- dispatchEvent(new RTMFPSocketEvent(RTMFPSocketEvent.CONNECT_SUCCESS));
- break;
- case "NetStream.Connect.Success" :
- break;
- case "NetStream.Publish.BadName" :
- fail();
- break;
- case "NetStream.Connect.Closed" :
- // we've disconnected from the peer
- // can reset to accept another
- // clear the publish stream and re-publish another
- dispatchEvent(new RTMFPSocketEvent(RTMFPSocketEvent.PEER_DISCONNECTED, recvStream));
- break;
- }
+ clearTimeout(connect_timeout);
+ dispatchEvent(new RTMFPSocketEvent(RTMFPSocketEvent.CONNECT_SUCCESS, recv_stream));
}
- private function onPeerConnect(peer:NetStream):Boolean
+ /* If we don't get a connection acknowledgement by the time this
+ timeout function is called, we punt. */
+ private function on_connect_timeout(peer:NetStream):void
{
- // establish a bidirectional stream with the peer
- if (peerID == null) {
- this.peer = peer.farID;
+ if (!this.connected) {
+ dispatchEvent(new RTMFPSocketEvent(RTMFPSocketEvent.CONNECT_FAILED, recv_stream));
}
-
- // disallow additional peers connecting to us
- if (peer.farID != peerID)
- return false;
-
- peer.send("setPeerConnectAcknowledged");
- dispatchEvent(new RTMFPSocketEvent(RTMFPSocketEvent.PEER_CONNECTED, peer));
-
- return true;
}
-
- private function onPeerConnectAcknowledged(event:Event):void
+
+ private function on_data_available(event:ProgressEvent):void
{
- dispatchEvent(new RTMFPSocketEvent(RTMFPSocketEvent.PEERING_SUCCESS, recvStream));
+ dispatchEvent(event);
}
-
- private function onPeerConnectTimeout(peer:NetStream):void
+
+ private function on_recv_stream_event(event:NetStatusEvent):void
{
- if (!recvStream.client) return;
- if (!RTMFPSocketClient(recvStream.client).peerConnectAcknowledged) {
- dispatchEvent(new RTMFPSocketEvent(RTMFPSocketEvent.PEERING_FAIL, recvStream));
- }
+ /* empty, here for symmetry */
}
- private function onSecurityErrorEvent(event:SecurityErrorEvent):void
+ /* This function gets called whenever someone tries to connect
+ to this socket's send_stream tuple. We don't want multiple
+ peers connecting at once, so we disallow that. The socket
+ acknowledges the connection back to the peer with the
+ SET_CONNECTION_ACKNOWLEDGED message. */
+ private function on_peer_connect(peer:NetStream):Boolean
{
- fail();
+ if (peer_connected) {
+ return false;
+ }
+
+ peer.send(RTMFPSocketClient.SET_CONNECT_ACKNOWLEDGED);
+
+ // need to do this in a timeout so that this function can
+ // return true to finalize the connection before firing the event
+ setTimeout(function (stream:NetStream):void {
+ dispatchEvent(new RTMFPSocketEvent(RTMFPSocketEvent.PEER_CONNECTED, stream));
+ }, 0, peer);
+
+ return true;
}
-
- private function onSendStreamEvent(event:NetStatusEvent):void
+
+ private function on_send_stream_event(event:NetStatusEvent):void
{
switch (event.info.code) {
- case ("NetStream.Publish.Start") :
- dispatchEvent(new RTMFPSocketEvent(RTMFPSocketEvent.PUBLISH_START));
- break;
- case ("NetStream.Play.Reset") :
- case ("NetStream.Play.Start") :
- break;
+ case "NetStream.Publish.Start":
+ dispatchEvent(new RTMFPSocketEvent(RTMFPSocketEvent.PUBLISH_STARTED));
+ break;
+ case "NetStream.Publish.BadName":
+ dispatchEvent(new RTMFPSocketEvent(RTMFPSocketEvent.PUBLISH_FAILED));
+ break;
+ default:
+ break;
}
}
- private function onRecvStreamEvent(event:NetStatusEvent):void
+
+ private function on_stream_disconnection_event(event:NetStatusEvent):void
{
- switch (event.info.code) {
- case ("NetStream.Publish.Start") :
- case ("NetStream.Play.Reset") :
- case ("NetStream.Play.Start") :
- break;
+ if (event.info.code == "NetStream.Connect.Closed") {
+ dispatchEvent(new RTMFPSocketEvent(RTMFPSocketEvent.PEER_DISCONNECTED));
+ //disconnect();
}
}
}
diff --git a/rtmfp/RTMFPSocketClient.as b/rtmfp/RTMFPSocketClient.as
index e2f93ef..7469a53 100644
--- a/rtmfp/RTMFPSocketClient.as
+++ b/rtmfp/RTMFPSocketClient.as
@@ -5,20 +5,20 @@ package rtmfp
import flash.events.ProgressEvent;
import flash.utils.ByteArray;
- [Event(name="peerConnectAcknowledged", type="flash.events.Event")]
+ [Event(name=RTMFPSocketClient.CONNECT_ACKNOWLEDGED, type="flash.events.Event")]
public dynamic class RTMFPSocketClient extends EventDispatcher {
- public static const PEER_CONNECT_ACKNOWLEDGED:String = "peerConnectAcknowledged";
+ public static const DATA_AVAILABLE:String = "data_available";
+ public static const CONNECT_ACKNOWLEDGED:String = "connectAcknowledged";
+ public static const SET_CONNECT_ACKNOWLEDGED:String = "set_connect_acknowledged";
private var _bytes:ByteArray;
- private var _peerID:String;
- private var _peerConnectAcknowledged:Boolean;
+ private var _connect_acknowledged:Boolean;
public function RTMFPSocketClient()
{
super();
_bytes = new ByteArray();
- _peerID = null;
- _peerConnectAcknowledged = false;
+ _connect_acknowledged = false;
}
public function get bytes():ByteArray
@@ -26,32 +26,22 @@ package rtmfp
return _bytes;
}
- public function dataAvailable(bytes:ByteArray):void
+ public function data_available(bytes:ByteArray):void
{
this._bytes.clear();
bytes.readBytes(this._bytes);
dispatchEvent(new ProgressEvent(ProgressEvent.SOCKET_DATA, false, false, this._bytes.bytesAvailable, this._bytes.length));
}
- public function get peerConnectAcknowledged():Boolean
+ public function get connect_acknowledged():Boolean
{
- return _peerConnectAcknowledged;
+ return _connect_acknowledged;
}
- public function setPeerConnectAcknowledged():void
+ public function set_connect_acknowledged():void
{
- _peerConnectAcknowledged = true;
- dispatchEvent(new Event(PEER_CONNECT_ACKNOWLEDGED));
- }
-
- public function get peerID():String
- {
- return _peerID;
- }
-
- public function set peerID(id:String):void
- {
- _peerID = id;
+ _connect_acknowledged = true;
+ dispatchEvent(new Event(CONNECT_ACKNOWLEDGED));
}
}
}
diff --git a/rtmfp/events/CirrusSocketEvent.as b/rtmfp/events/CirrusSocketEvent.as
new file mode 100644
index 0000000..831ad73
--- /dev/null
+++ b/rtmfp/events/CirrusSocketEvent.as
@@ -0,0 +1,22 @@
+package rtmfp.events
+{
+ import flash.events.Event;
+
+ public class CirrusSocketEvent extends Event
+ {
+ public static const CONNECT_CLOSED:String = "connectClosed";
+ public static const CONNECT_FAILED:String = "connectFailed";
+ public static const CONNECT_SUCCESS:String = "connectSuccess";
+ public static const HELLO_RECEIVED:String = "helloReceived";
+
+ public var peer:String;
+ public var stream:String;
+
+ public function CirrusSocketEvent(type:String, peer:String = null, stream:String = null, bubbles:Boolean = false, cancelable:Boolean = false)
+ {
+ super(type, bubbles, cancelable);
+ this.peer = peer;
+ this.stream = stream;
+ }
+ }
+}
diff --git a/rtmfp/events/FacilitatorSocketEvent.as b/rtmfp/events/FacilitatorSocketEvent.as
new file mode 100644
index 0000000..a0599aa
--- /dev/null
+++ b/rtmfp/events/FacilitatorSocketEvent.as
@@ -0,0 +1,22 @@
+package rtmfp.events
+{
+ import flash.events.Event;
+
+ public class FacilitatorSocketEvent extends Event
+ {
+ public static const CONNECT_CLOSED:String = "connectClosed";
+ public static const CONNECT_FAILED:String = "connectFailed";
+ public static const CONNECT_SUCCESS:String = "connectSuccess";
+ public static const REGISTRATION_RECEIVED:String = "registrationReceived";
+ public static const REGISTRATION_FAILED:String = "registrationFailed";
+ public static const REGISTRATIONS_EMPTY:String = "registrationsEmpty";
+
+ public var client:String;
+
+ public function FacilitatorSocketEvent(type:String, client:String = null, bubbles:Boolean = false, cancelable:Boolean = false)
+ {
+ super(type, bubbles, cancelable);
+ this.client = client;
+ }
+ }
+}
diff --git a/rtmfp/events/RTMFPSocketEvent.as b/rtmfp/events/RTMFPSocketEvent.as
index 5bc08e5..87a7e09 100644
--- a/rtmfp/events/RTMFPSocketEvent.as
+++ b/rtmfp/events/RTMFPSocketEvent.as
@@ -5,20 +5,21 @@ package rtmfp.events
public class RTMFPSocketEvent extends Event
{
+ public static const CONNECT_FAILED:String = "connectFailed";
public static const CONNECT_SUCCESS:String = "connectSuccess";
- public static const CONNECT_FAIL:String = "connectFail";
- public static const PUBLISH_START:String = "publishStart";
+ public static const CONNECT_CLOSED:String = "connectClosed"
public static const PEER_CONNECTED:String = "peerConnected";
public static const PEER_DISCONNECTED:String = "peerDisconnected";
- public static const PEERING_SUCCESS:String = "peeringSuccess";
- public static const PEERING_FAIL:String = "peeringFail";
+ public static const PLAY_STARTED:String = "playStarted";
+ public static const PUBLISH_STARTED:String = "publishStarted";
+ public static const PUBLISH_FAILED:String = "publishFailed";
public var stream:NetStream;
- public function RTMFPSocketEvent(type:String, streamVal:NetStream = null, bubbles:Boolean = false, cancelable:Boolean = false)
+ public function RTMFPSocketEvent(type:String, stream:NetStream = null, bubbles:Boolean = false, cancelable:Boolean = false)
{
super(type, bubbles, cancelable);
- stream = streamVal;
+ this.stream = stream;
}
}
}
diff --git a/rtmfpcat.as b/rtmfpcat.as
index d01bb37..866175e 100644
--- a/rtmfpcat.as
+++ b/rtmfpcat.as
@@ -5,46 +5,54 @@ package
import flash.display.StageScaleMode;
import flash.text.TextField;
import flash.text.TextFormat;
- import flash.net.Socket;
import flash.events.Event;
- import flash.events.EventDispatcher;
- import flash.events.IOErrorEvent;
- import flash.events.NetStatusEvent;
- import flash.events.ProgressEvent;
- import flash.events.SecurityErrorEvent;
- import flash.utils.ByteArray;
- import flash.utils.setTimeout;
+ import flash.utils.clearInterval;
+ import flash.utils.setInterval;
- import rtmfp.RTMFPSocket;
- import rtmfp.events.RTMFPSocketEvent;
+ import rtmfp.CirrusSocket;
+ import rtmfp.FacilitatorSocket;
+ import rtmfp.ProxyPair;
+ import rtmfp.events.CirrusSocketEvent;
+ import rtmfp.events.FacilitatorSocketEvent;
public class rtmfpcat extends Sprite
{
- /* David's relay (nickname 3VXRyxz67OeRoqHn) that also serves a
- crossdomain policy. */
- private const DEFAULT_TOR_PROXY_ADDR:Object = {
- host: "173.255.221.44",
- port: 9001
- };
- /* Nate's facilitator -- also serving a crossdomain policy */
+ /* Adobe's Cirrus server and Nate's key */
+ private const DEFAULT_CIRRUS_ADDR:String = "rtmfp://p2p.rtmfp.net";
+ private const DEFAULT_CIRRUS_KEY:String = RTMFP::CIRRUS_KEY;
+
+ /* Nate's facilitator -- serves a crossdomain policy */
private const DEFAULT_FACILITATOR_ADDR:Object = {
host: "128.12.179.80",
port: 9002
};
+
private const DEFAULT_TOR_CLIENT_ADDR:Object = {
host: "127.0.0.1",
port: 3333
};
+
+ /* David's relay (nickname 3VXRyxz67OeRoqHn) that also serves a
+ crossdomain policy. */
+ private const DEFAULT_TOR_PROXY_ADDR:Object = {
+ host: "173.255.221.44",
+ port: 9001
+ };
+
+ /* Poll facilitator every 3 sec if in proxy mode and haven't found
+ anyone to proxy */
+ private const DEFAULT_FAC_POLL_INTERVAL:uint = 3000;
- // Milliseconds.
- private const FACILITATOR_POLL_INTERVAL:int = 10000;
-
+ // Socket to Cirrus server
+ private var s_c:CirrusSocket;
// Socket to facilitator.
- private var s_f:Socket;
- // Socket to RTMFP peer (flash proxy).
- private var s_r:RTMFPSocket;
- // Socket to local Tor client.
- private var s_t:Socket;
+ private var s_f:FacilitatorSocket;
+ // Handle local-remote traffic
+ private var p_p:ProxyPair;
+
+ private var proxy_mode:Boolean;
+
+ private var fac_poll_interval:uint;
/* TextField for debug output. */
private var output_text:TextField;
@@ -52,14 +60,6 @@ package
private var fac_addr:Object;
private var tor_addr:Object;
- private var proxy_mode:Boolean;
-
- public function puts(s:String):void
- {
- output_text.appendText(s + "\n");
- output_text.scrollV = output_text.maxScrollV;
- }
-
public function rtmfpcat()
{
// Absolute positioning.
@@ -72,7 +72,8 @@ package
output_text.background = true;
output_text.backgroundColor = 0x001f0f;
output_text.textColor = 0x44cc44;
-
+ addChild(output_text);
+
puts("Starting.");
// Wait until the query string parameters are loaded.
this.loaderInfo.addEventListener(Event.COMPLETE, loaderinfo_complete);
@@ -82,11 +83,10 @@ package
{
var fac_spec:String;
var tor_spec:String;
-
+
puts("Parameters loaded.");
proxy_mode = (this.loaderInfo.parameters["proxy"] != null);
- addChild(output_text);
fac_spec = this.loaderInfo.parameters["facilitator"];
if (fac_spec) {
@@ -109,10 +109,11 @@ package
return;
}
} else {
- if (proxy_mode)
+ if (proxy_mode) {
tor_addr = DEFAULT_TOR_PROXY_ADDR;
- else
+ } else {
tor_addr = DEFAULT_TOR_CLIENT_ADDR;
+ }
}
main();
@@ -121,105 +122,106 @@ package
/* The main logic begins here, after start-up issues are taken care of. */
private function main():void
{
- establishRTMFPConnection();
+ establish_cirrus_connection();
}
- private function establishRTMFPConnection():void
+ private function establish_cirrus_connection():void
{
- s_r = new RTMFPSocket();
- s_r.addEventListener(RTMFPSocketEvent.CONNECT_SUCCESS, function (e:Event):void {
- puts("Cirrus: connected with id " + s_r.id + ".");
- establishFacilitatorConnection();
+ 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) {
+ fac_poll_interval = setInterval(establish_facilitator_connection, DEFAULT_FAC_POLL_INTERVAL);
+ } else {
+ establish_facilitator_connection();
+ }
});
- s_r.addEventListener(RTMFPSocketEvent.CONNECT_FAIL, function (e:Event):void {
+ s_c.addEventListener(CirrusSocketEvent.CONNECT_FAILED, function (e:CirrusSocketEvent):void {
puts("Error: failed to connect to Cirrus.");
});
- s_r.addEventListener(RTMFPSocketEvent.PUBLISH_START, function(e:RTMFPSocketEvent):void {
- puts("Publishing started.");
+ s_c.addEventListener(CirrusSocketEvent.CONNECT_CLOSED, function (e:CirrusSocketEvent):void {
+ puts("Cirrus: closed connection.");
});
- s_r.addEventListener(RTMFPSocketEvent.PEER_CONNECTED, function(e:RTMFPSocketEvent):void {
- puts("Peer connected.");
- });
- s_r.addEventListener(RTMFPSocketEvent.PEER_DISCONNECTED, function(e:RTMFPSocketEvent):void {
- puts("Peer disconnected.");
- });
- s_r.addEventListener(RTMFPSocketEvent.PEERING_SUCCESS, function(e:RTMFPSocketEvent):void {
- puts("Peering success.");
- establishTorConnection();
- });
- s_r.addEventListener(RTMFPSocketEvent.PEERING_FAIL, function(e:RTMFPSocketEvent):void {
- puts("Peering fail.");
- });
- s_r.addEventListener(ProgressEvent.SOCKET_DATA, function (e:ProgressEvent):void {
- var bytes:ByteArray = new ByteArray();
- s_r.readBytes(bytes);
- puts("RTMFP: read " + bytes.length + " bytes.");
- s_t.writeBytes(bytes);
+
+ 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) {
+ start_proxy_pair();
+ s_c.send_hello(e.peer);
+ }
+ p_p.connect(e.peer, e.stream);
});
-
- s_r.connect();
+
+ s_c.connect(DEFAULT_CIRRUS_ADDR, DEFAULT_CIRRUS_KEY);
}
- private function establishTorConnection():void
+ private function establish_facilitator_connection():void
{
- s_t = new Socket();
- s_t.addEventListener(Event.CONNECT, function (e:Event):void {
- puts("Tor: connected to " + tor_addr.host + ":" + tor_addr.port + ".");
- });
- s_t.addEventListener(Event.CLOSE, function (e:Event):void {
- puts("Tor: closed connection.");
- });
- s_t.addEventListener(IOErrorEvent.IO_ERROR, function (e:IOErrorEvent):void {
- puts("Tor: I/O error: " + e.text + ".");
- });
- 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 + " bytes.");
- s_r.writeBytes(bytes);
- });
- s_t.addEventListener(SecurityErrorEvent.SECURITY_ERROR, function (e:SecurityErrorEvent):void {
- puts("Tor: security error: " + e.text + ".");
+ s_f = new FacilitatorSocket();
+ s_f.addEventListener(FacilitatorSocketEvent.CONNECT_SUCCESS, function (e:Event):void {
+ if (proxy_mode) {
+ puts("Facilitator: getting registration.");
+ s_f.get_registration();
+ } else {
+ puts("Facilitator: posting registration.");
+ s_f.post_registration(s_c.id);
+ }
});
-
- s_t.connect(tor_addr.host, tor_addr.port);
+ s_f.addEventListener(FacilitatorSocketEvent.CONNECT_FAILED, function (e:Event):void {
+ puts("Facilitator: connect failed.");
+ });
+ s_f.addEventListener(FacilitatorSocketEvent.CONNECT_CLOSED, function (e:Event):void {
+ puts("Facilitator: connect closed.");
+ });
+
+ if (proxy_mode) {
+ s_f.addEventListener(FacilitatorSocketEvent.REGISTRATION_RECEIVED, function (e:FacilitatorSocketEvent):void {
+ puts("Facilitator: got registration " + e.client);
+ clearInterval(fac_poll_interval);
+ start_proxy_pair();
+ s_c.send_hello(e.client);
+ });
+ s_f.addEventListener(FacilitatorSocketEvent.REGISTRATIONS_EMPTY, function (e:Event):void {
+ puts("Facilitator: no registrations available.");
+ });
+ } else {
+ s_f.addEventListener(FacilitatorSocketEvent.REGISTRATION_FAILED, function (e:Event):void {
+ puts("Facilitator: registration failed.");
+ });
+ }
+ s_f.connect(fac_addr.host, fac_addr.port);
}
-
- private function establishFacilitatorConnection():void
+
+ private function start_proxy_pair():void
{
- s_f = new Socket();
- s_f.addEventListener(Event.CONNECT, function (e:Event):void {
- puts("Facilitator: connected to " + fac_addr.host + ":" + fac_addr.port + ".");
- if (proxy_mode) s_f.writeUTFBytes("GET / HTTP/1.0\r\n\r\n");
- else s_f.writeUTFBytes("POST / HTTP/1.0\r\n\r\nclient=" + s_r.id + "\r\n");
- });
- s_f.addEventListener(Event.CLOSE, function (e:Event):void {
- puts("Facilitator: connection closed.");
+ puts("Starting proxy pair on stream " + s_c.local_stream_name);
+ p_p = new ProxyPair(this, s_c, tor_addr.host, tor_addr.port);
+ p_p.addEventListener(Event.CONNECT, function (e:Event):void {
+ puts("ProxyPair: connected!");
+ });
+ p_p.addEventListener(Event.CLOSE, function (e:Event):void {
+ puts("ProxyPair: connection closed.");
+ p_p = null;
if (proxy_mode) {
- setTimeout(establishFacilitatorConnection, FACILITATOR_POLL_INTERVAL);
+ fac_poll_interval = setInterval(establish_facilitator_connection, DEFAULT_FAC_POLL_INTERVAL);
+ } else {
+ establish_facilitator_connection();
}
});
- s_f.addEventListener(IOErrorEvent.IO_ERROR, function (e:IOErrorEvent):void {
- puts("Facilitator: I/O error: " + e.text + ".");
- });
- s_f.addEventListener(ProgressEvent.SOCKET_DATA, function (e:ProgressEvent):void {
- var clientID:String = s_f.readMultiByte(e.bytesLoaded, "utf-8");
- puts("Facilitator: got \"" + clientID + "\"");
- if (clientID != "Registration list empty") {
- puts("Connecting to " + clientID + ".");
- s_r.peer = clientID;
- }
- });
- s_f.addEventListener(SecurityErrorEvent.SECURITY_ERROR, function (e:SecurityErrorEvent):void {
- puts("Facilitator: security error: " + e.text + ".");
- });
-
- s_f.connect(fac_addr.host, fac_addr.port);
+ p_p.listen(s_c.local_stream_name);
}
/* Parse an address in the form "host:port". Returns an Object with
keys "host" (String) and "port" (int). Returns null on error. */
- private static function parse_addr_spec(spec:String):Object
+ private function parse_addr_spec(spec:String):Object
{
var parts:Array;
var addr:Object;
@@ -233,5 +235,11 @@ package
return addr;
}
+
+ public function puts(s:String):void
+ {
+ output_text.appendText(s + "\n");
+ output_text.scrollV = output_text.maxScrollV;
+ }
}
}
[View Less]
1
0

12 Jun '11
commit 7a302499ef39988d560790a220d4f05f5f1b2e9b
Author: Nate Hardison <nate(a)rescomp-09-154551.stanford.edu>
Date: Thu Jun 2 04:02:36 2011 -0700
Adding some comments and removing clutter
---
rtmfp/CirrusSocket.as | 2 ++
rtmfp/RTMFPSocket.as | 17 +----------------
2 files changed, 3 insertions(+), 16 deletions(-)
diff --git a/rtmfp/CirrusSocket.as b/rtmfp/CirrusSocket.as
index d9996f2..9e97c7d 100644
--- a/rtmfp/CirrusSocket.as
+++ b/rtmfp/CirrusSocket.as
@@ -49,6 +49,8 @@…
[View More] package rtmfp
connection.addEventListener(NetStatusEvent.NET_STATUS, on_net_status_event);
connection.addEventListener(IOErrorEvent.IO_ERROR, on_io_error_event);
connection.addEventListener(SecurityErrorEvent.SECURITY_ERROR, on_security_error_event);
+
+ /* Set up a client object to handle the hello callback */
var client:Object = new Object();
client.onRelay = on_hello;
connection.client = client;
diff --git a/rtmfp/RTMFPSocket.as b/rtmfp/RTMFPSocket.as
index 783a0e0..6e9a45e 100644
--- a/rtmfp/RTMFPSocket.as
+++ b/rtmfp/RTMFPSocket.as
@@ -45,8 +45,7 @@ package rtmfp
}
/* Tears down this RTMFPSocket, closing both its streams.
- To be used when destroying this object. If you just want
- to disconnect from a client, call disconnect() below */
+ To be used when destroying this object. */
public function close():void
{
if (send_stream != null) {
@@ -82,19 +81,6 @@ package rtmfp
RTMFPSocketClient(recv_stream.client).connect_acknowledged);
}
- public function disconnect():void
- {
- if (recv_stream != null) {
- if (recv_stream.client != null) {
- recv_stream.client.removeEventListener(ProgressEvent.SOCKET_DATA, on_data_available);
- recv_stream.client.removeEventListener(RTMFPSocketClient.CONNECT_ACKNOWLEDGED, on_connect_acknowledged);
- }
- recv_stream.removeEventListener(NetStatusEvent.NET_STATUS, on_recv_stream_event);
- recv_stream.close();
- recv_stream = null;
- }
- }
-
/* In RTMFP, you open a listening socket by publishing a named
stream that others can connect to instead of listening on a port.
You register this stream with the Cirrus server via the Cirrus
@@ -132,7 +118,6 @@ package rtmfp
}
}
-
public function writeBytes(bytes:ByteArray):void
{
if (send_stream != null && peer_connected) {
[View Less]
1
0

[flashproxy/master] Changing terminology to use relay/proxy instead of Tor/RTMFP
by dcf@torproject.org 12 Jun '11
by dcf@torproject.org 12 Jun '11
12 Jun '11
commit 3a8df84e3bb8dcc16d411a4c2fb9f4e005f313c8
Author: Nate Hardison <nate(a)rescomp-09-154551.stanford.edu>
Date: Thu Jun 2 13:47:34 2011 -0700
Changing terminology to use relay/proxy instead of Tor/RTMFP
---
rtmfp/ProxyPair.as | 112 ++++++++++++++++++++++++++--------------------------
rtmfpcat.as | 26 ++++++------
2 files changed, 69 insertions(+), 69 deletions(-)
diff --git a/rtmfp/ProxyPair.as b/rtmfp/ProxyPair.as
index fb184cc..159abde 100644
--- a/rtmfp/…
[View More]ProxyPair.as
+++ b/rtmfp/ProxyPair.as
@@ -18,126 +18,126 @@ package rtmfp
{
private var ui:rtmfpcat;
- private var s_r:RTMFPSocket;
- private var s_t:Socket;
+ private var s_p:RTMFPSocket;
+ private var s_r:Socket;
- private var tor_host:String;
- private var tor_port:uint;
+ private var relay_host:String;
+ private var relay_port:uint;
- private var p2t_schedule:Array;
- private var t2p_schedule:Array;
+ private var p2r_schedule:Array;
+ private var r2p_schedule:Array;
// Bytes per second. Set to undefined to disable limit.
public const RATE_LIMIT:Number = 10000;
// Seconds.
- private const RATE_LIMIT_HISTORY:Number = 5.0;
+ private const RATE_LIMIT_HISrelayY:Number = 5.0;
private var rate_limit:RateLimit;
// Callback id.
private var flush_id:uint;
- public function ProxyPair(ui:rtmfpcat, s_c:CirrusSocket, tor_host:String, tor_port:uint)
+ public function ProxyPair(ui:rtmfpcat, s_c:CirrusSocket, relay_host:String, relay_port:uint)
{
this.ui = ui;
- this.tor_host = tor_host;
- this.tor_port = tor_port;
+ this.relay_host = relay_host;
+ this.relay_port = relay_port;
- this.p2t_schedule = new Array();
- this.t2p_schedule = new Array();
+ this.p2r_schedule = new Array();
+ this.r2p_schedule = new Array();
if (RATE_LIMIT)
- rate_limit = new BucketRateLimit(RATE_LIMIT * RATE_LIMIT_HISTORY, RATE_LIMIT_HISTORY);
+ rate_limit = new BucketRateLimit(RATE_LIMIT * RATE_LIMIT_HISrelayY, RATE_LIMIT_HISrelayY);
else
rate_limit = new RateUnlimit();
setup_rtmfp_socket(s_c);
- setup_tor_socket();
+ setup_relay_socket();
}
public function close():void
{
+ if (s_p.connected) {
+ s_p.close();
+ }
if (s_r.connected) {
s_r.close();
}
- if (s_t.connected) {
- s_t.close();
- }
dispatchEvent(new Event(Event.CLOSE));
}
public function connect(peer:String, stream:String):void
{
- s_r.connect(peer, stream);
+ s_p.connect(peer, stream);
}
public function get connected():Boolean
{
- return (s_r.connected && s_t.connected);
+ return (s_p.connected && s_r.connected);
}
public function listen(stream:String):void
{
- s_r.listen(stream);
+ s_p.listen(stream);
}
private function setup_rtmfp_socket(s_c:CirrusSocket):void
{
- s_r = new RTMFPSocket(s_c);
- s_r.addEventListener(RTMFPSocketEvent.CONNECT_FAILED, function (e:RTMFPSocketEvent):void {
+ s_p = new RTMFPSocket(s_c);
+ s_p.addEventListener(RTMFPSocketEvent.CONNECT_FAILED, function (e:RTMFPSocketEvent):void {
ui.puts("Peering failed.");
});
- s_r.addEventListener(RTMFPSocketEvent.CONNECT_SUCCESS, function (e:RTMFPSocketEvent):void {
+ s_p.addEventListener(RTMFPSocketEvent.CONNECT_SUCCESS, function (e:RTMFPSocketEvent):void {
ui.puts("Peering success.");
- s_t.connect(tor_host, tor_port);
+ s_r.connect(relay_host, relay_port);
});
- s_r.addEventListener(RTMFPSocketEvent.PEER_CONNECTED, function (e:RTMFPSocketEvent):void {
+ s_p.addEventListener(RTMFPSocketEvent.PEER_CONNECTED, function (e:RTMFPSocketEvent):void {
ui.puts("Peer connected.");
});
- s_r.addEventListener(RTMFPSocketEvent.PEER_DISCONNECTED, function (e:RTMFPSocketEvent):void {
+ s_p.addEventListener(RTMFPSocketEvent.PEER_DISCONNECTED, function (e:RTMFPSocketEvent):void {
ui.puts("Peer disconnected.");
close();
});
- s_r.addEventListener(RTMFPSocketEvent.PLAY_STARTED, function (e:RTMFPSocketEvent):void {
+ s_p.addEventListener(RTMFPSocketEvent.PLAY_STARTED, function (e:RTMFPSocketEvent):void {
ui.puts("Play started.");
});
- s_r.addEventListener(RTMFPSocketEvent.PUBLISH_STARTED, function (e:RTMFPSocketEvent):void {
+ s_p.addEventListener(RTMFPSocketEvent.PUBLISH_STARTED, function (e:RTMFPSocketEvent):void {
ui.puts("Publishing started.");
});
- s_r.addEventListener(ProgressEvent.SOCKET_DATA, proxy_to_tor);
+ s_p.addEventListener(ProgressEvent.SOCKET_DATA, proxy_to_relay);
}
- private function setup_tor_socket():void
+ private function setup_relay_socket():void
{
- s_t = new Socket();
- s_t.addEventListener(Event.CONNECT, function (e:Event):void {
- ui.puts("Tor: connected to " + tor_host + ":" + tor_port + ".");
+ s_r = new Socket();
+ s_r.addEventListener(Event.CONNECT, function (e:Event):void {
+ ui.puts("Relay: connected to " + relay_host + ":" + relay_port + ".");
dispatchEvent(new Event(Event.CONNECT));
});
- s_t.addEventListener(Event.CLOSE, function (e:Event):void {
- ui.puts("Tor: closed connection.");
+ s_r.addEventListener(Event.CLOSE, function (e:Event):void {
+ ui.puts("Relay: closed connection.");
close();
});
- s_t.addEventListener(IOErrorEvent.IO_ERROR, function (e:IOErrorEvent):void {
- ui.puts("Tor: I/O error: " + e.text + ".");
+ s_r.addEventListener(IOErrorEvent.IO_ERROR, function (e:IOErrorEvent):void {
+ ui.puts("Relay: I/O error: " + e.text + ".");
close();
});
- s_t.addEventListener(SecurityErrorEvent.SECURITY_ERROR, function (e:SecurityErrorEvent):void {
- ui.puts("Tor: security error: " + e.text + ".");
+ s_r.addEventListener(SecurityErrorEvent.SECURITY_ERROR, function (e:SecurityErrorEvent):void {
+ ui.puts("Relay: security error: " + e.text + ".");
close();
});
- s_t.addEventListener(ProgressEvent.SOCKET_DATA, tor_to_proxy);
+ s_r.addEventListener(ProgressEvent.SOCKET_DATA, relay_to_proxy);
}
- private function tor_to_proxy(e:ProgressEvent):void
+ private function relay_to_proxy(e:ProgressEvent):void
{
- t2p_schedule.push(e.bytesLoaded);
+ r2p_schedule.push(e.bytesLoaded);
flush();
}
- private function proxy_to_tor(e:ProgressEvent):void
+ private function proxy_to_relay(e:ProgressEvent):void
{
- p2t_schedule.push(e.bytesLoaded);
+ p2r_schedule.push(e.bytesLoaded);
flush();
}
@@ -148,34 +148,34 @@ package rtmfp
clearTimeout(flush_id);
flush_id = undefined;
- if (!(s_r.connected && s_t.connected))
+ if (!(s_p.connected && s_r.connected))
/* Can't do anything until both sockets are connected. */
return;
- while (!rate_limit.is_limited() && (p2t_schedule.length > 0 || t2p_schedule.length > 0)) {
+ while (!rate_limit.is_limited() && (p2r_schedule.length > 0 || r2p_schedule.length > 0)) {
var numBytes:uint;
var bytes:ByteArray;
- if (p2t_schedule.length > 0) {
- numBytes = p2t_schedule.shift();
+ if (p2r_schedule.length > 0) {
+ numBytes = p2r_schedule.shift();
bytes = new ByteArray();
- s_r.readBytes(bytes, 0, numBytes);
+ s_p.readBytes(bytes, 0, numBytes);
ui.puts("ProxyPair: RTMFP: read " + bytes.length + " bytes.");
- s_t.writeBytes(bytes);
+ s_r.writeBytes(bytes);
rate_limit.update(numBytes);
}
- if (t2p_schedule.length > 0) {
- numBytes = t2p_schedule.shift();
+ if (r2p_schedule.length > 0) {
+ numBytes = r2p_schedule.shift();
bytes = new ByteArray();
- s_t.readBytes(bytes, 0, numBytes);
- ui.puts("ProxyPair: Tor: read " + bytes.length + " bytes.");
- s_r.writeBytes(bytes);
+ s_r.readBytes(bytes, 0, numBytes);
+ ui.puts("ProxyPair: Relay: read " + bytes.length + " bytes.");
+ s_p.writeBytes(bytes);
rate_limit.update(numBytes);
}
}
/* Call again when safe, if necessary. */
- if (p2t_schedule.length > 0 || t2p_schedule.length > 0)
+ if (p2r_schedule.length > 0 || r2p_schedule.length > 0)
flush_id = setTimeout(flush, rate_limit.when() * 1000);
}
}
diff --git a/rtmfpcat.as b/rtmfpcat.as
index 2273bc9..713fc45 100644
--- a/rtmfpcat.as
+++ b/rtmfpcat.as
@@ -33,7 +33,7 @@ package
/* David's relay (nickname 3VXRyxz67OeRoqHn) that also serves a
crossdomain policy. */
- private const DEFAULT_TOR_PROXY_ADDR:Object = {
+ private const DEFAULT_TOR_RELAY_ADDR:Object = {
host: "173.255.221.44",
port: 9001
};
@@ -56,7 +56,7 @@ package
private var output_text:TextField;
private var fac_addr:Object;
- private var tor_addr:Object;
+ private var relay_addr:Object;
public function rtmfpcat()
{
@@ -86,7 +86,7 @@ package
private function loaderinfo_complete(e:Event):void
{
var fac_spec:String;
- var tor_spec:String;
+ var relay_spec:String;
puts("Parameters loaded.");
@@ -104,20 +104,20 @@ package
} else {
fac_addr = DEFAULT_FACILITATOR_ADDR;
}
-
- tor_spec = this.loaderInfo.parameters["tor"];
- if (tor_spec) {
- puts("Tor spec: \"" + tor_spec + "\"");
- tor_addr = parse_addr_spec(tor_spec);
- if (!tor_addr) {
- puts("Error: Tor spec must be in the form \"host:port\".");
+
+ relay_spec = this.loaderInfo.parameters["relay"];
+ if (relay_spec) {
+ puts("Relay spec: \"" + relay_spec + "\"");
+ relay_addr = parse_addr_spec(relay_spec);
+ if (!relay_addr) {
+ puts("Error: Relay spec must be in the form \"host:port\".");
return;
}
} else {
if (proxy_mode) {
- tor_addr = DEFAULT_TOR_PROXY_ADDR;
+ relay_addr = DEFAULT_TOR_RELAY_ADDR;
} else {
- tor_addr = DEFAULT_TOR_CLIENT_ADDR;
+ relay_addr = DEFAULT_TOR_CLIENT_ADDR;
}
}
@@ -206,7 +206,7 @@ package
private function start_proxy_pair():void
{
puts("Starting proxy pair on stream " + s_c.local_stream_name);
- p_p = new ProxyPair(this, s_c, tor_addr.host, tor_addr.port);
+ p_p = new ProxyPair(this, s_c, relay_addr.host, relay_addr.port);
p_p.addEventListener(Event.CONNECT, function (e:Event):void {
puts("ProxyPair: connected!");
});
[View Less]
1
0

[flashproxy/master] Merge branch 'rtmfp' of ssh://upload.bamsoftware.com/~dcf/flashproxy into rtmfp
by dcf@torproject.org 12 Jun '11
by dcf@torproject.org 12 Jun '11
12 Jun '11
commit 07752417d9a42099bc0c869b0ebac1862f72baa4
Merge: 7c4ca7b a7cdef5
Author: Nate Hardison <nate(a)rescomp-09-154551.stanford.edu>
Date: Thu Jun 2 03:46:27 2011 -0700
Merge branch 'rtmfp' of ssh://upload.bamsoftware.com/~dcf/flashproxy into rtmfp
badge_con_counter.png | Bin 0 -> 270 bytes
return_of_the_rtmfpcat.as | 234 +++++++++++++++++++++++++++++++++++++--------
2 files changed, 192 insertions(+), 42 deletions(-)
1
0