blob: fcfcc9999295fe87b7edc83ac9a34830d76ef584 [file] [log] [blame]
Alexander Afanasyev1d2642a2012-01-02 16:20:05 -08001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2011 University of California, Los Angeles
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
19 */
20
21
22#include "ns3/core-module.h"
23#include "ns3/network-module.h"
24#include "ns3/point-to-point-module.h"
25#include "ns3/NDNabstraction-module.h"
26#include "ns3/point-to-point-grid.h"
27#include "ns3/ipv4-global-routing-helper.h"
28#include "ns3/random-variable.h"
Alexander Afanasyev36d5c2a2012-01-02 19:09:19 -080029#include "ns3/internet-module.h"
30#include "ns3/applications-module.h"
Alexander Afanasyeve4c2ece2012-01-11 10:44:40 -080031#include "ns3/config-store.h"
Alexander Afanasyev1d2642a2012-01-02 16:20:05 -080032
33#include <iostream>
34#include <sstream>
35#include <map>
36#include <list>
37#include <set>
38#include "ns3/rocketfuel-topology-reader.h"
39
40#include <boost/lexical_cast.hpp>
41#include <boost/foreach.hpp>
42
43using namespace ns3;
44using namespace std;
45using namespace boost;
46
47NS_LOG_COMPONENT_DEFINE ("Scenario");
48
Alexander Afanasyevf9d8fbe2012-01-10 02:03:15 -080049// void PrintTime ()
50// {
51// cout << "Progress: " << Simulator::Now ().ToDouble (Time::S) << "s" << endl;
Alexander Afanasyev1d2642a2012-01-02 16:20:05 -080052
Alexander Afanasyevf9d8fbe2012-01-10 02:03:15 -080053// Simulator::Schedule (Seconds (1.0), PrintTime);
54// }
Alexander Afanasyev1d2642a2012-01-02 16:20:05 -080055
56class Experiment
57{
58public:
Alexander Afanasyevc4f88282012-01-03 11:27:20 -080059 Experiment ()
60 : m_rand (0,52)
Alexander Afanasyevf9d8fbe2012-01-10 02:03:15 -080061 , reader (0)
Alexander Afanasyevc4f88282012-01-03 11:27:20 -080062 { }
Alexander Afanasyevf9d8fbe2012-01-10 02:03:15 -080063
64 ~Experiment ()
65 {
66 if (reader != 0) delete reader;
67 }
68
Alexander Afanasyev1d2642a2012-01-02 16:20:05 -080069 void
Alexander Afanasyevf9d8fbe2012-01-10 02:03:15 -080070 ConfigureTopology ()
Alexander Afanasyev1d2642a2012-01-02 16:20:05 -080071 {
Alexander Afanasyev36d5c2a2012-01-02 19:09:19 -080072 Names::Clear ();
Alexander Afanasyevf9d8fbe2012-01-10 02:03:15 -080073 cout << "Configure Topology\n";
74 if (reader != 0) delete reader;
75 reader = new RocketfuelWeightsReader ("/sprint");
Alexander Afanasyev36d5c2a2012-01-02 19:09:19 -080076
Alexander Afanasyev1d2642a2012-01-02 16:20:05 -080077 string weights ("./src/NDNabstraction/examples/sprint-pops.weights");
78 string latencies ("./src/NDNabstraction/examples/sprint-pops.latencies");
79 string positions ("./src/NDNabstraction/examples/sprint-pops.positions");
Alexander Afanasyev1d2642a2012-01-02 16:20:05 -080080
Alexander Afanasyevf9d8fbe2012-01-10 02:03:15 -080081 reader->SetFileName (positions);
82 reader->SetFileType (RocketfuelWeightsReader::POSITIONS);
83 reader->Read ();
Alexander Afanasyev1d2642a2012-01-02 16:20:05 -080084
Alexander Afanasyevf9d8fbe2012-01-10 02:03:15 -080085 reader->SetFileName (weights);
86 reader->SetFileType (RocketfuelWeightsReader::WEIGHTS);
87 reader->Read ();
Alexander Afanasyev1d2642a2012-01-02 16:20:05 -080088
Alexander Afanasyevf9d8fbe2012-01-10 02:03:15 -080089 reader->SetFileName (latencies);
90 reader->SetFileType (RocketfuelWeightsReader::LATENCIES);
91 reader->Read ();
Alexander Afanasyev1d2642a2012-01-02 16:20:05 -080092
Alexander Afanasyevf9d8fbe2012-01-10 02:03:15 -080093 reader->Commit ();
94 }
95
96 void InstallCcnxStack ()
97 {
Alexander Afanasyev1d2642a2012-01-02 16:20:05 -080098 InternetStackHelper stack;
99 Ipv4GlobalRoutingHelper ipv4RoutingHelper ("ns3::Ipv4GlobalRoutingOrderedNexthops");
100 stack.SetRoutingHelper (ipv4RoutingHelper);
Alexander Afanasyevf9d8fbe2012-01-10 02:03:15 -0800101 stack.Install (reader->GetNodes ());
Alexander Afanasyev1d2642a2012-01-02 16:20:05 -0800102
Alexander Afanasyevf9d8fbe2012-01-10 02:03:15 -0800103 reader->AssignIpv4Addresses (Ipv4Address ("10.0.0.0"));
Alexander Afanasyevc4f88282012-01-03 11:27:20 -0800104
Alexander Afanasyev1d2642a2012-01-02 16:20:05 -0800105 // Install CCNx stack
Alexander Afanasyevf9d8fbe2012-01-10 02:03:15 -0800106 cout << "Installing CCNx stack\n";
Alexander Afanasyev1d2642a2012-01-02 16:20:05 -0800107 CcnxStackHelper ccnxHelper;
Alexander Afanasyevc4f88282012-01-03 11:27:20 -0800108 ccnxHelper.SetForwardingStrategy ("ns3::CcnxBestRouteStrategy");
Alexander Afanasyev1d2642a2012-01-02 16:20:05 -0800109 ccnxHelper.EnableLimits (true, Seconds(0.1));
110 ccnxHelper.SetDefaultRoutes (false);
111 ccnxHelper.InstallAll ();
Alexander Afanasyev1d2642a2012-01-02 16:20:05 -0800112
Alexander Afanasyevc4f88282012-01-03 11:27:20 -0800113 // // Populate FIB based on IPv4 global routing controller
114 ccnxHelper.InstallFakeGlobalRoutes ();
115 ccnxHelper.InstallRoutesToAll ();
Alexander Afanasyev1d2642a2012-01-02 16:20:05 -0800116 }
Alexander Afanasyev36d5c2a2012-01-02 19:09:19 -0800117
Alexander Afanasyevf9d8fbe2012-01-10 02:03:15 -0800118 void InstallIpStack ()
Alexander Afanasyev1d2642a2012-01-02 16:20:05 -0800119 {
Alexander Afanasyevf9d8fbe2012-01-10 02:03:15 -0800120 InternetStackHelper stack;
121 stack.Install (reader->GetNodes ());
122 reader->AssignIpv4Addresses (Ipv4Address ("10.0.0.0"));
123
124 Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
125 }
126
127 void
128 GenerateRandomPairs (uint16_t numStreams)
129 {
130 m_pairs.clear ();
131 // map<uint32_t, set<uint32_t> > streams;
132 set<uint32_t> usedNodes;
Alexander Afanasyev1d2642a2012-01-02 16:20:05 -0800133
134 uint16_t createdStreams = 0;
135 uint16_t guard = 0;
136 while (createdStreams < numStreams && guard < (numeric_limits<uint16_t>::max ()-1))
137 {
138 guard ++;
Alexander Afanasyevf9d8fbe2012-01-10 02:03:15 -0800139
Alexander Afanasyev1d2642a2012-01-02 16:20:05 -0800140 uint32_t node1_num = m_rand.GetValue ();
141 uint32_t node2_num = m_rand.GetValue ();
142
143 if (node1_num == node2_num)
144 continue;
145
Alexander Afanasyevf9d8fbe2012-01-10 02:03:15 -0800146 if (usedNodes.count (node1_num) > 0 ||
147 usedNodes.count (node2_num) > 0 )
148 {
149 continue; // don't reuse nodes
150 }
151
152 usedNodes.insert (node1_num);
153 usedNodes.insert (node2_num);
154
155 m_pairs.push_back (make_tuple (node1_num, node2_num));
156 createdStreams ++;
157 }
158 }
159
160 ApplicationContainer
161 AddCcnxApplications ()
162 {
163 ApplicationContainer apps;
164
165 for (list<tuple<uint32_t,uint32_t> >::iterator i = m_pairs.begin (); i != m_pairs.end (); i++)
166 {
167 uint32_t node1_num = i->get<0> ();
168 uint32_t node2_num = i->get<1> ();
Alexander Afanasyev1d2642a2012-01-02 16:20:05 -0800169
170 Ptr<Node> node1 = Names::Find<Node> ("/sprint", lexical_cast<string> (node1_num));
171 Ptr<Node> node2 = Names::Find<Node> ("/sprint", lexical_cast<string> (node2_num));
172
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800173 CcnxAppHelper consumerHelper ("ns3::CcnxConsumerWindow");
Alexander Afanasyev1d2642a2012-01-02 16:20:05 -0800174 consumerHelper.SetPrefix ("/" + lexical_cast<string> (node2->GetId ()));
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800175 // consumerHelper.SetAttribute ("MeanRate", StringValue ("2Mbps"));
Alexander Afanasyev36d5c2a2012-01-02 19:09:19 -0800176 consumerHelper.SetAttribute ("Size", StringValue ("1.983642578125")); //to make sure max seq # is 2000
Alexander Afanasyev1d2642a2012-01-02 16:20:05 -0800177
178 CcnxAppHelper producerHelper ("ns3::CcnxProducer");
179 producerHelper.SetPrefix ("/" + lexical_cast<string> (node2->GetId ()));
180
181 apps.Add
182 (consumerHelper.Install (node1));
183
184 apps.Add
185 (producerHelper.Install (node2));
Alexander Afanasyev1d2642a2012-01-02 16:20:05 -0800186 }
187
188 return apps;
189 }
190
Alexander Afanasyevf9d8fbe2012-01-10 02:03:15 -0800191 ApplicationContainer
192 AddTcpApplications ()
193 {
194 ApplicationContainer apps;
195
196 uint32_t streamId = 0;
197 const static uint32_t base_port = 10;
198 for (list<tuple<uint32_t,uint32_t> >::iterator i = m_pairs.begin (); i != m_pairs.end (); i++)
199 {
200 uint32_t node1_num = i->get<0> ();
201 uint32_t node2_num = i->get<1> ();
202
203 Ptr<Node> node1 = Names::Find<Node> ("/sprint", lexical_cast<string> (node2_num));
204 Ptr<Node> node2 = Names::Find<Node> ("/sprint", lexical_cast<string> (node1_num));
205
206 Ptr<Ipv4> ipv4 = node1->GetObject<Ipv4> ();
207 // ipv4->GetAddress (0, 0);
208
209 // to make sure we don't reuse the same port numbers for different flows, just make all port numbers unique
210 PacketSinkHelper consumerHelper ("ns3::TcpSocketFactory",
211 InetSocketAddress (Ipv4Address::GetAny (), base_port + streamId));
212
213 BulkSendHelper producerHelper ("ns3::TcpSocketFactory",
214 InetSocketAddress (ipv4->GetAddress (1, 0).GetLocal (), base_port + streamId));
215 // cout << "SendTo: " << ipv4->GetAddress (1, 0).GetLocal () << endl;
216 producerHelper.SetAttribute ("MaxBytes", UintegerValue (2081040)); // equal to 2001 ccnx packets
217
218 apps.Add
219 (consumerHelper.Install (node1));
220
221 apps.Add
222 (producerHelper.Install (node2));
223
224 streamId++;
225 }
226
227 return apps;
228 }
229
230
Alexander Afanasyev36d5c2a2012-01-02 19:09:19 -0800231 void
232 Run (const Time &finishTime)
233 {
234 cout << "Run Simulation.\n";
235 Simulator::Stop (finishTime);
Alexander Afanasyevf9d8fbe2012-01-10 02:03:15 -0800236 // Simulator::Schedule (Seconds (1.0), PrintTime);
Alexander Afanasyev36d5c2a2012-01-02 19:09:19 -0800237 Simulator::Run ();
238 Simulator::Destroy ();
239 cout << "Done.\n";
240 }
Alexander Afanasyev1d2642a2012-01-02 16:20:05 -0800241
242 UniformVariable m_rand;
Alexander Afanasyevf9d8fbe2012-01-10 02:03:15 -0800243 RocketfuelWeightsReader *reader;
244
245 list<tuple<uint32_t,uint32_t> > m_pairs;
Alexander Afanasyev1d2642a2012-01-02 16:20:05 -0800246};
247
248
249int
250main (int argc, char *argv[])
251{
252 cout << "Begin congestion-pop scenario\n";
253
254 Config::SetDefault ("ns3::PointToPointNetDevice::DataRate", StringValue ("1Mbps"));
Alexander Afanasyev359bfb72012-01-09 18:42:50 -0800255 Config::SetDefault ("ns3::DropTailQueue::MaxPackets", StringValue ("60"));
Alexander Afanasyevf9d8fbe2012-01-10 02:03:15 -0800256 Config::SetDefault ("ns3::TcpSocket::SegmentSize", StringValue ("1040"));
257
258 Config::SetDefault ("ns3::BulkSendApplication::SendSize", StringValue ("1040"));
Alexander Afanasyev1d2642a2012-01-02 16:20:05 -0800259
Alexander Afanasyeve4c2ece2012-01-11 10:44:40 -0800260 Config::SetDefault ("ns3::ConfigStore::Filename", StringValue ("attributes.xml"));
261 Config::SetDefault ("ns3::ConfigStore::Mode", StringValue ("Save"));
262 Config::SetDefault ("ns3::ConfigStore::FileFormat", StringValue ("Xml"));
263
Alexander Afanasyev36d5c2a2012-01-02 19:09:19 -0800264 uint32_t maxRuns = 1;
265 uint32_t startRun = 0;
Alexander Afanasyev1d2642a2012-01-02 16:20:05 -0800266 CommandLine cmd;
Alexander Afanasyev36d5c2a2012-01-02 19:09:19 -0800267 cmd.AddValue ("start", "Initial run number", startRun);
268 cmd.AddValue ("runs", "Number of runs", maxRuns);
Alexander Afanasyev1d2642a2012-01-02 16:20:05 -0800269 cmd.Parse (argc, argv);
270
Alexander Afanasyeve4c2ece2012-01-11 10:44:40 -0800271 // ConfigStore config;
272 // config.ConfigureDefaults ();
273
Alexander Afanasyev36d5c2a2012-01-02 19:09:19 -0800274 for (uint32_t run = startRun; run < startRun + maxRuns; run++)
Alexander Afanasyev1d2642a2012-01-02 16:20:05 -0800275 {
Alexander Afanasyev36d5c2a2012-01-02 19:09:19 -0800276 Config::SetGlobal ("RngRun", IntegerValue (run));
Alexander Afanasyevc4f88282012-01-03 11:27:20 -0800277 cout << "seed = " << SeedManager::GetSeed () << ", run = " << SeedManager::GetRun () << endl;
278
Alexander Afanasyev36d5c2a2012-01-02 19:09:19 -0800279 Experiment experiment;
280 cout << "Run " << run << endl;
Alexander Afanasyevc4f88282012-01-03 11:27:20 -0800281 string prefix = "run-" + lexical_cast<string> (run) + "-";
Alexander Afanasyev1d2642a2012-01-02 16:20:05 -0800282
Alexander Afanasyevf9d8fbe2012-01-10 02:03:15 -0800283 experiment.GenerateRandomPairs (20);
Alexander Afanasyevc4f88282012-01-03 11:27:20 -0800284 ofstream of_nodes ((prefix + "apps.log").c_str ());
Alexander Afanasyevf9d8fbe2012-01-10 02:03:15 -0800285 for (list<tuple<uint32_t,uint32_t> >::iterator i = experiment.m_pairs.begin (); i != experiment.m_pairs.end (); i++)
Alexander Afanasyev1d2642a2012-01-02 16:20:05 -0800286 {
Alexander Afanasyevf9d8fbe2012-01-10 02:03:15 -0800287 of_nodes << "From " << i->get<0> ()
288 << " to " << i->get<1> ();
Alexander Afanasyevc4f88282012-01-03 11:27:20 -0800289 of_nodes << "\n";
Alexander Afanasyev1d2642a2012-01-02 16:20:05 -0800290 }
Alexander Afanasyevc4f88282012-01-03 11:27:20 -0800291 of_nodes.close ();
Alexander Afanasyev36d5c2a2012-01-02 19:09:19 -0800292
Alexander Afanasyevf9d8fbe2012-01-10 02:03:15 -0800293 cout << "NDN experiment\n";
294 // NDN
295 {
296 experiment.ConfigureTopology ();
297 experiment.InstallCcnxStack ();
298 ApplicationContainer apps = experiment.AddCcnxApplications ();
Alexander Afanasyev1d2642a2012-01-02 16:20:05 -0800299
Alexander Afanasyevf9d8fbe2012-01-10 02:03:15 -0800300 for (uint32_t i = 0; i < apps.GetN () / 2; i++)
301 {
Alexander Afanasyev06b42ec2012-01-11 19:05:36 -0800302 apps.Get (i*2)->SetStartTime (Seconds (1+i));
303 apps.Get (i*2 + 1)->SetStartTime (Seconds (1+i));
Alexander Afanasyevf9d8fbe2012-01-10 02:03:15 -0800304 }
305
306 CcnxTraceHelper traceHelper;
307 // traceHelper.EnableRateL3All (prefix + "rate-trace.log");
308 // traceHelper.EnableSeqsAppAll ("ns3::CcnxConsumerCbr", prefix + "consumers-seqs.log");
309 traceHelper.EnableSeqsAppAll ("ns3::CcnxConsumerWindow", prefix + "consumers-seqs.log");
Alexander Afanasyeve4c2ece2012-01-11 10:44:40 -0800310 traceHelper.EnableWindowsAll (prefix + "windows.log");
Alexander Afanasyevf9d8fbe2012-01-10 02:03:15 -0800311
Alexander Afanasyeve4c2ece2012-01-11 10:44:40 -0800312 // config.ConfigureAttributes ();
Alexander Afanasyevf9d8fbe2012-01-10 02:03:15 -0800313 experiment.Run (Seconds (200.0));
314 }
315
316 cout << "TCP experiment\n";
317 // TCP
318 {
319 experiment.ConfigureTopology ();
320 experiment.InstallIpStack ();
321 ApplicationContainer apps = experiment.AddTcpApplications ();
322
Alexander Afanasyevf9d8fbe2012-01-10 02:03:15 -0800323 CcnxTraceHelper traceHelper;
324 traceHelper.EnableIpv4SeqsAppAll (prefix + "tcp-consumers-seqs.log");
Alexander Afanasyev06b42ec2012-01-11 19:05:36 -0800325 traceHelper.EnableWindowsTcpAll (prefix + "tcp-windows.log");
326
327 for (uint32_t i = 0; i < apps.GetN () / 2; i++)
328 {
329 apps.Get (i*2)->SetStartTime (Seconds (1+i));
330
331 apps.Get (i*2 + 1)->SetStartTime (Seconds (1+i));
332
333 // cout << "Node: " << apps.Get (i*2 + 1)->GetNode ()->GetId () << "\n";
334 // care only about BulkSender
335 Simulator::Schedule (Seconds (1+i+0.01),
336 &CcnxTraceHelper::TcpConnect, &traceHelper, apps.Get (i*2)->GetNode ());
337
338 Simulator::Schedule (Seconds (1+i+0.01),
339 &CcnxTraceHelper::TcpConnect, &traceHelper, apps.Get (i*2 + 1)->GetNode ());
340 }
Alexander Afanasyevf9d8fbe2012-01-10 02:03:15 -0800341
342 experiment.Run (Seconds (200.0));
343 }
Alexander Afanasyev1d2642a2012-01-02 16:20:05 -0800344 }
345
Alexander Afanasyev36d5c2a2012-01-02 19:09:19 -0800346 // cout << "Finish congestion-pop scenario\n";
Alexander Afanasyev1d2642a2012-01-02 16:20:05 -0800347 return 0;
348}