public static void Main(string []args) {
if (args.Length < 1) {
Console.WriteLine("please specify the number edge protocol.");
Environment.Exit(0);
}
if (args.Length < 2) {
Console.WriteLine("please specify the number of p2p nodes.");
Environment.Exit(0);
}
if (args.Length < 3) {
Console.WriteLine("please specify the number of missing edges.");
Environment.Exit(0);
}
string proto = "function";
try {
proto = args[0].Trim();
} catch(Exception) {}
bool tunnel = false;
int base_port = 54000;
int network_size = Int32.Parse(args[1]);
int missing_count = Int32.Parse(args[2]);
try {
tunnel = args[3].Trim().Equals("tunnel");
} catch (Exception) {}
Console.WriteLine("use tunnel edges: {0}", tunnel);
Random rand = new Random();
ArrayList missing_edges = new ArrayList();
for (int i = 0; i < missing_count; i++) {
int idx = -1;
int left, right;
do {
idx = rand.Next(0, network_size);
left = (idx + 1)%network_size;
if (idx == 0) {
right = network_size - 1;
} else {
right = idx - 1;
}
} while (missing_edges.Contains(idx));// ||
//missing_edges.Contains(left) ||
//missing_edges.Contains(right));
Console.WriteLine("Will drop a left edge on idx {0}: ", idx);
missing_edges.Add(idx);
}
//
// Sort missing edges.
//
missing_edges.Sort();
SortedList dist = new SortedList();
//
// Compute the average distance between missing edges.
//
if (missing_count > 1) {
for (int i = 0; i < missing_count; i++) {
int idx = (int) missing_edges[i];
int idx_next;
int d;
if (i == missing_count - 1) {
idx_next = (int) missing_edges[0];
d = (network_size - 1) - idx + idx_next;
} else {
idx_next = (int) missing_edges[i+1];
d = idx_next - idx - 1;
}
if (!dist.Contains(d)) {
dist[d] = 0;
} else {
int c = (int) dist[d];
dist[d] = c + 1;
}
}
}
double sum = 0.0;
int num = 0;
Console.WriteLine("distribution of missing edges separation");
foreach(DictionaryEntry de in dist) {
int k = (int) de.Key;
int c = (int) de.Value;
Console.WriteLine("{0} {1}", k, c);
sum = sum + k*c;
num = num + c;
}
Console.WriteLine("average separation: {0}", (double) sum/num);
string brunet_namespace = "testing";
Console.WriteLine("Initializing...");
var RemoteTA = new List<TransportAddress>();
for(int i = 0; i < network_size; i++) {
if (proto.Equals("udp")) {
RemoteTA.Add(TransportAddressFactory.CreateInstance("brunet.udp://localhost:" + (base_port + i)));
} else if (proto.Equals("function")) {
RemoteTA.Add(TransportAddressFactory.CreateInstance("brunet.function://localhost:" + (base_port + i)));
}
}
for(int i = 0; i < network_size; i++) {
AHAddress address = new AHAddress(new RNGCryptoServiceProvider());
Node node = new StructuredNode(address, brunet_namespace);
_sorted_node_list.Add((Address) address, node);
_node_list.Add(node);
RouteTestHandler test_handler = new RouteTestHandler();
node.GetTypeSource(new PType(routing_test)).Subscribe(test_handler, address.ToMemBlock());
RpcManager rpc_man = node.Rpc;
rpc_man.AddHandler("rpc_routing_test", new RpcRoutingTestHandler(node));
}
for (int i = 0; i < network_size; i++) {
Node node = (Node) _sorted_node_list.GetByIndex(i);
Console.WriteLine("Configuring node: {0} ", node.Address);
TAAuthorizer ta_auth = null;
if (missing_edges.Contains(i)) {
int remote_port;
if (i == network_size - 1) {
remote_port = base_port;
} else {
remote_port = base_port + i + 1;
}
PortTAAuthorizer port_auth = new PortTAAuthorizer(remote_port);
Console.WriteLine("Adding a port TA authorizer at: {0} for remote port: {1}", base_port + i, remote_port);
ArrayList arr_tas = new ArrayList();
arr_tas.Add(port_auth);
arr_tas.Add(new ConstantAuthorizer(TAAuthorizer.Decision.Allow));
ta_auth = new SeriesTAAuthorizer(arr_tas);
}
if (proto.Equals("udp")) {
node.AddEdgeListener(new UdpEdgeListener(base_port + i, null, ta_auth));
} else if(proto.Equals("function")) {
node.AddEdgeListener(new FunctionEdgeListener(base_port + i, -1.00, ta_auth));
}
if (tunnel) {
Console.WriteLine("Adding a tunnel edge listener");
node.AddEdgeListener(new Relay.RelayEdgeListener(node));
}
_node_to_port[node] = base_port + i;
node.RemoteTAs = RemoteTA;
}
//start nodes one by one.
for (int i = 0; i < network_size; i++) {
Node node = (Node) _node_list[i];
Console.WriteLine("Starting node: {0}, {1}", i, node.Address);
node.Connect();
Console.WriteLine("Going to sleep for 2 seconds.");
System.Threading.Thread.Sleep(2000);
}
//wait for 300000 more seconds
Console.WriteLine("Going to sleep for 300000 seconds.");
System.Threading.Thread.Sleep(300000);
bool complete = CheckStatus();
int count = 0;
//
// Send a large number of packets as exact packets to random destinations
// and make sure exact routing is perfect.
//
for (int i = 0; i < network_size; i++) {
for (int j = 0; j < network_size; j++) {
int src_idx = i;
int dest_idx = j;
Node src_node = (Node) _sorted_node_list.GetByIndex(src_idx);
Node dest_node = (Node) _sorted_node_list.GetByIndex(dest_idx);
//Console.WriteLine("{0} -> {1}", src_idx, dest_idx);
Address dest_address = (Address) dest_node.Address;
ISender s = new AHExactSender(src_node, dest_address);
MemBlock p = dest_address.ToMemBlock();
s.Send(new CopyList(new PType(routing_test), p));
_sent++;
//System.Threading.Thread.Sleep(10);
s.Send(new CopyList(new PType(routing_test), p));
_sent++;
//System.Threading.Thread.Sleep(10);
}
}
//wait for 10 more seconds
Console.WriteLine("Going to sleep for 10 seconds.");
System.Threading.Thread.Sleep(10000);
Console.WriteLine("Final statistics");
lock(_class_lock) {
Console.WriteLine("Sent: {0}, Received: {1}, Wrongly routed: {2}",
_sent, _received, _wrongly_routed);
}
int missing_rpcs = 0;
int correct_rpcs = 0;
int incorrect_rpcs = 0;
Hashtable queue_to_address = new Hashtable();
for (int i = 0; i < network_size; i++) {
for (int j = 0; j < network_size; j++) {
int src_idx = i;
int dest_idx = j;
Node src_node = (Node) _sorted_node_list.GetByIndex(src_idx);
Node dest_node = (Node) _sorted_node_list.GetByIndex(dest_idx);
//Console.WriteLine("{0} -> {1}", src_idx, dest_idx);
Address dest_address = (Address) dest_node.Address;
ISender s = new AHExactSender(src_node, dest_address);
RpcManager rpc_man = src_node.Rpc;
Channel q = new Channel();
lock (_class_lock) {
queue_to_address[q] = dest_address;
}
q.CloseAfterEnqueue();
q.CloseEvent += delegate(object o, EventArgs cargs) {
lock(_class_lock) {
Channel qu = (Channel) o;
if (qu.Count == 0) {
missing_rpcs++;
}
queue_to_address.Remove(qu);
}
};
q.EnqueueEvent += delegate(object o, EventArgs cargs) {
lock(_class_lock) {
Channel qu = (Channel) o;
RpcResult rpc_reply = (RpcResult) qu.Peek();
byte []result = (byte[]) rpc_reply.Result;
Address target = new AHAddress(result);
if (target.Equals(queue_to_address[qu])) {
correct_rpcs++;
} else {
incorrect_rpcs++;
}
}
};
rpc_man.Invoke(s, q, "rpc_routing_test.GetIdentification", new object[]{});
}
}
//wait for 10 more seconds
while (true) {
int c = -1;
lock(_class_lock) {
c = incorrect_rpcs + missing_rpcs + correct_rpcs;
}
if (c < network_size*network_size) {
Console.WriteLine("Going to sleep for 10 seconds.");
System.Threading.Thread.Sleep(10000);
} else {
break;
}
}
Console.WriteLine("Final statistics");
Console.WriteLine("correct rpcs: {0}, incorrect rpcs: {1}, missing rpcs: {2}",
correct_rpcs, incorrect_rpcs, missing_rpcs);
System.Environment.Exit(1);
}
}