Bug 946 - Rocketfuel topology dataset support for topology reader
This commit is contained in:
@@ -65,6 +65,7 @@ many cases referencing the Bugzilla bug number
|
||||
- bug 858 - support MSG_PEEK in IPv4/IPv6 raw socket
|
||||
- bug 932 - Support IP_HDRINCL option for Ipv4RawSocket
|
||||
- bug 871 - naming for WifiPhyStandard
|
||||
- bug 946 - Rocketfuel topology dataset support for topology reader
|
||||
|
||||
Known issues
|
||||
------------
|
||||
|
||||
1944
examples/topology-read/RocketFuel_toposample_1239_weights.txt
Normal file
1944
examples/topology-read/RocketFuel_toposample_1239_weights.txt
Normal file
File diff suppressed because it is too large
Load Diff
@@ -62,7 +62,7 @@ int main (int argc, char *argv[])
|
||||
|
||||
// Set up command line parameters used to control the experiment.
|
||||
CommandLine cmd;
|
||||
cmd.AddValue ("format", "Format to use for data input [Orbis|Inet].",
|
||||
cmd.AddValue ("format", "Format to use for data input [Orbis|Inet|Rocketfuel].",
|
||||
format);
|
||||
cmd.AddValue ("input", "Name of the input file.",
|
||||
input);
|
||||
|
||||
407
src/contrib/topology-read/rocketfuel-topology-reader.cc
Normal file
407
src/contrib/topology-read/rocketfuel-topology-reader.cc
Normal file
@@ -0,0 +1,407 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2010 Hajime Tazaki
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Hajime Tazaki (tazaki@sfc.wide.ad.jp)
|
||||
*/
|
||||
|
||||
#include <fstream>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <regex.h>
|
||||
|
||||
#include "ns3/log.h"
|
||||
#include "rocketfuel-topology-reader.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("RocketfuelTopologyReader");
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (RocketfuelTopologyReader);
|
||||
|
||||
TypeId RocketfuelTopologyReader::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::RocketfuelTopologyReader")
|
||||
.SetParent<Object> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
RocketfuelTopologyReader::RocketfuelTopologyReader ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
}
|
||||
|
||||
RocketfuelTopologyReader::~RocketfuelTopologyReader ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
}
|
||||
|
||||
/* uid @loc [+] [bb] (num_neigh) [&ext] -> <nuid-1> <nuid-2> ... {-euid} ... =name[!] rn */
|
||||
|
||||
#define REGMATCH_MAX 16
|
||||
|
||||
#define START "^"
|
||||
#define END "$"
|
||||
#define SPACE "[ \t]+"
|
||||
#define MAYSPACE "[ \t]*"
|
||||
|
||||
#define ROCKETFUEL_MAPS_LINE \
|
||||
START "(-*[0-9]+)" SPACE "(@[?A-Za-z0-9,+]+)" SPACE \
|
||||
"(\\+)*" MAYSPACE "(bb)*" MAYSPACE \
|
||||
"\\(([0-9]+)\\)" SPACE "(&[0-9]+)*" MAYSPACE \
|
||||
"->" MAYSPACE "(<[0-9 \t<>]+>)*" MAYSPACE \
|
||||
"(\\{-[0-9\\{\\} \t-]+\\})*" SPACE \
|
||||
"=([A-Za-z0-9.!-]+)" SPACE "r([0-9])" \
|
||||
MAYSPACE END
|
||||
|
||||
#define ROCKETFUEL_WEIGHTS_LINE \
|
||||
START "([^ \t]+)" SPACE "([^ \t]+)" SPACE "([0-9.]+)" MAYSPACE END
|
||||
|
||||
int linksNumber = 0;
|
||||
int nodesNumber = 0;
|
||||
std::map<std::string, Ptr<Node> > nodeMap;
|
||||
|
||||
NodeContainer
|
||||
RocketfuelTopologyReader::GenerateFromMapsFile (int argc, char *argv[])
|
||||
{
|
||||
std::string uid;
|
||||
std::string loc;
|
||||
std::string ptr;
|
||||
std::string name;
|
||||
std::string nuid;
|
||||
bool dns = false;
|
||||
bool bb = false;
|
||||
int num_neigh = 0;
|
||||
int ext_conn = 0;
|
||||
int radius = 0;
|
||||
std::vector <std::string> neigh_list;
|
||||
NodeContainer nodes;
|
||||
|
||||
uid = argv[0];
|
||||
loc = argv[1];
|
||||
|
||||
if (argv[2])
|
||||
dns = true;
|
||||
|
||||
if (argv[3])
|
||||
bb = true;
|
||||
|
||||
num_neigh = ::atoi (argv[4]);
|
||||
|
||||
/* the first char should be '&' */
|
||||
if (argv[5])
|
||||
{
|
||||
ext_conn = ::atoi (&argv[5][1]);
|
||||
}
|
||||
|
||||
/* neighbors */
|
||||
if (argv[6])
|
||||
{
|
||||
char *nbr;
|
||||
char *stringp = argv[6];
|
||||
while ((nbr = strsep (&stringp, " \t")) != NULL)
|
||||
{
|
||||
nbr[strlen (nbr) - 1] = '\0';
|
||||
neigh_list.push_back (nbr + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* externs */
|
||||
if (argv[7])
|
||||
{
|
||||
// euid = argv[7];
|
||||
}
|
||||
|
||||
/* name */
|
||||
if (argv[8])
|
||||
{
|
||||
name = argv[8];
|
||||
}
|
||||
|
||||
radius = ::atoi (&argv[9][1]);
|
||||
if (radius > 0)
|
||||
{
|
||||
return nodes;
|
||||
}
|
||||
|
||||
/* uid @loc [+] [bb] (num_neigh) [&ext] -> <nuid-1> <nuid-2> ... {-euid} ... =name[!] rn */
|
||||
NS_LOG_INFO ("Load Node[" << uid << "]: location: " << loc << " dns: " << dns
|
||||
<< " bb: " << bb << " neighbors: " << neigh_list.size ()
|
||||
<< "(" << "%d" << ") externals: \"%s\"(%d) "
|
||||
<< "name: " << name << " radius: " << radius);
|
||||
|
||||
// Create node and link
|
||||
if (!uid.empty ())
|
||||
{
|
||||
if (nodeMap[uid] == 0)
|
||||
{
|
||||
Ptr<Node> tmpNode = CreateObject<Node> ();
|
||||
nodeMap[uid] = tmpNode;
|
||||
nodes.Add (tmpNode);
|
||||
nodesNumber++;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < neigh_list.size (); ++i)
|
||||
{
|
||||
nuid = neigh_list[i];
|
||||
|
||||
if (nuid.empty ())
|
||||
{
|
||||
return nodes;
|
||||
}
|
||||
|
||||
if (nodeMap[nuid] == 0)
|
||||
{
|
||||
Ptr<Node> tmpNode = CreateObject<Node> ();
|
||||
nodeMap[nuid] = tmpNode;
|
||||
nodes.Add (tmpNode);
|
||||
nodesNumber++;
|
||||
}
|
||||
NS_LOG_INFO (linksNumber << ":" << nodesNumber << " From: " << uid << " to: " << nuid);
|
||||
Link link (nodeMap[uid], uid, nodeMap[nuid], nuid);
|
||||
AddLink (link);
|
||||
linksNumber++;
|
||||
}
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
|
||||
NodeContainer
|
||||
RocketfuelTopologyReader::GenerateFromWeightsFile (int argc, char *argv[])
|
||||
{
|
||||
/* uid @loc [+] [bb] (num_neigh) [&ext] -> <nuid-1> <nuid-2> ... {-euid} ... =name[!] rn */
|
||||
std::string sname;
|
||||
std::string tname;
|
||||
double weight;
|
||||
char *endptr;
|
||||
NodeContainer nodes;
|
||||
|
||||
sname = argv[0];
|
||||
tname = argv[1];
|
||||
weight = strtod (argv[2], &endptr);
|
||||
if (*endptr != '\0')
|
||||
{
|
||||
NS_LOG_WARN ("invalid weight: " << argv[2]);
|
||||
return nodes;
|
||||
}
|
||||
|
||||
// Create node and link
|
||||
if (!sname.empty () && !tname.empty ())
|
||||
{
|
||||
if (nodeMap[sname] == 0)
|
||||
{
|
||||
Ptr<Node> tmpNode = CreateObject<Node> ();
|
||||
nodeMap[sname] = tmpNode;
|
||||
nodes.Add (tmpNode);
|
||||
nodesNumber++;
|
||||
}
|
||||
|
||||
if (nodeMap[tname] == 0)
|
||||
{
|
||||
Ptr<Node> tmpNode = CreateObject<Node> ();
|
||||
nodeMap[tname] = tmpNode;
|
||||
nodes.Add (tmpNode);
|
||||
nodesNumber++;
|
||||
}
|
||||
NS_LOG_INFO (linksNumber << ":" << nodesNumber << " From: " << sname << " to: " << tname);
|
||||
TopologyReader::ConstLinksIterator iter;
|
||||
bool found = false;
|
||||
for (iter = LinksBegin (); iter != LinksEnd (); iter++)
|
||||
{
|
||||
if ((iter->GetFromNode () == nodeMap[tname]) &&
|
||||
(iter->GetToNode () == nodeMap[sname]))
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
Link link (nodeMap[sname], sname, nodeMap[tname], tname);
|
||||
AddLink (link);
|
||||
linksNumber++;
|
||||
}
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
|
||||
enum RocketfuelTopologyReader::RF_FileType
|
||||
RocketfuelTopologyReader::GetFileType (const char *line)
|
||||
{
|
||||
int ret;
|
||||
regmatch_t regmatch[REGMATCH_MAX];
|
||||
regex_t regex;
|
||||
char errbuf[512];
|
||||
|
||||
// Check whether MAPS file or not
|
||||
ret = regcomp (®ex, ROCKETFUEL_MAPS_LINE, REG_EXTENDED|REG_NEWLINE);
|
||||
if (ret != 0)
|
||||
{
|
||||
regerror (ret, ®ex, errbuf, sizeof (errbuf));
|
||||
return RF_UNKNOWN;
|
||||
}
|
||||
ret = regexec (®ex, line, REGMATCH_MAX, regmatch, 0);
|
||||
if (ret != REG_NOMATCH)
|
||||
{
|
||||
regfree (®ex);
|
||||
return RF_MAPS;
|
||||
}
|
||||
regfree (®ex);
|
||||
|
||||
// Check whether Weights file or not
|
||||
ret = regcomp (®ex, ROCKETFUEL_WEIGHTS_LINE, REG_EXTENDED|REG_NEWLINE);
|
||||
if (ret != 0)
|
||||
{
|
||||
regerror (ret, ®ex, errbuf, sizeof (errbuf));
|
||||
return RF_UNKNOWN;
|
||||
}
|
||||
ret = regexec (®ex, line, REGMATCH_MAX, regmatch, 0);
|
||||
if (ret != REG_NOMATCH)
|
||||
{
|
||||
regfree (®ex);
|
||||
return RF_WEIGHTS;
|
||||
}
|
||||
regfree (®ex);
|
||||
|
||||
return RF_UNKNOWN;
|
||||
}
|
||||
|
||||
|
||||
NodeContainer
|
||||
RocketfuelTopologyReader::Read (void)
|
||||
{
|
||||
std::ifstream topgen;
|
||||
topgen.open (GetFileName ().c_str ());
|
||||
NodeContainer nodes;
|
||||
|
||||
std::istringstream lineBuffer;
|
||||
std::string line;
|
||||
int lineNumber = 0;
|
||||
char errbuf[512];
|
||||
|
||||
if (!topgen.is_open ())
|
||||
{
|
||||
NS_LOG_WARN ("Couldn't open the file " << GetFileName ());
|
||||
return nodes;
|
||||
}
|
||||
|
||||
while (!topgen.eof ())
|
||||
{
|
||||
int ret;
|
||||
int argc;
|
||||
char *argv[REGMATCH_MAX];
|
||||
char *buf;
|
||||
enum RF_FileType ftype;
|
||||
|
||||
lineNumber++;
|
||||
line.clear ();
|
||||
lineBuffer.clear ();
|
||||
|
||||
getline (topgen, line);
|
||||
buf = (char *)line.c_str ();
|
||||
|
||||
if (lineNumber == 1)
|
||||
{
|
||||
ftype = GetFileType (buf);
|
||||
if (ftype == RF_UNKNOWN)
|
||||
{
|
||||
NS_LOG_INFO ("Unknown File Format (" << GetFileName () << ")");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
regmatch_t regmatch[REGMATCH_MAX];
|
||||
regex_t regex;
|
||||
|
||||
if (ftype == RF_MAPS)
|
||||
{
|
||||
ret = regcomp (®ex, ROCKETFUEL_MAPS_LINE, REG_EXTENDED|REG_NEWLINE);
|
||||
if (ret != 0)
|
||||
{
|
||||
regerror (ret, ®ex, errbuf, sizeof (errbuf));
|
||||
break;
|
||||
}
|
||||
|
||||
ret = regexec (®ex, buf, REGMATCH_MAX, regmatch, 0);
|
||||
if (ret == REG_NOMATCH)
|
||||
{
|
||||
NS_LOG_WARN ("match failed (maps file): %s" << buf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (ftype == RF_WEIGHTS)
|
||||
{
|
||||
ret = regcomp (®ex, ROCKETFUEL_WEIGHTS_LINE, REG_EXTENDED|REG_NEWLINE);
|
||||
if (ret != 0)
|
||||
{
|
||||
regerror (ret, ®ex, errbuf, sizeof (errbuf));
|
||||
break;
|
||||
}
|
||||
|
||||
ret = regexec (®ex, buf, REGMATCH_MAX, regmatch, 0);
|
||||
if (ret == REG_NOMATCH)
|
||||
{
|
||||
NS_LOG_WARN ("match failed (weights file): %s" << buf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
line = strdup (buf);
|
||||
argc = 0;
|
||||
|
||||
/* regmatch[0] is the entire strings that matched */
|
||||
for (int i = 1; i < REGMATCH_MAX; i++)
|
||||
{
|
||||
if (regmatch[i].rm_so == -1)
|
||||
{
|
||||
argv[i-1] = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
line[regmatch[i].rm_eo] = '\0';
|
||||
argv[i-1] = &line[regmatch[i].rm_so];
|
||||
argc = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (ftype == RF_MAPS)
|
||||
{
|
||||
nodes.Add (GenerateFromMapsFile (argc, argv));
|
||||
}
|
||||
else if (ftype == RF_WEIGHTS)
|
||||
{
|
||||
nodes.Add (GenerateFromWeightsFile (argc, argv));
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_LOG_WARN ("Unsupported file format (only Maps/Weights are supported)");
|
||||
}
|
||||
|
||||
regfree (®ex);
|
||||
}
|
||||
|
||||
|
||||
topgen.close ();
|
||||
|
||||
NS_LOG_INFO ("Rocketfuel topology created with " << nodesNumber << " nodes and " << linksNumber << " links");
|
||||
return nodes;
|
||||
}
|
||||
|
||||
} /* namespace ns3 */
|
||||
|
||||
90
src/contrib/topology-read/rocketfuel-topology-reader.h
Normal file
90
src/contrib/topology-read/rocketfuel-topology-reader.h
Normal file
@@ -0,0 +1,90 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2010 Hajime Tazaki
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Hajime Tazaki (tazaki@sfc.wide.ad.jp)
|
||||
*/
|
||||
|
||||
#ifndef __ROCKETFUEL_TOPOLOGY_READER_H__
|
||||
#define __ROCKETFUEL_TOPOLOGY_READER_H__
|
||||
|
||||
#include "ns3/nstime.h"
|
||||
|
||||
#include "topology-reader.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// --------------------------------------------
|
||||
/**
|
||||
* \ingroup topology
|
||||
* \brief Topology file reader (Rocketfuel-format type).
|
||||
*
|
||||
* http://www.cs.washington.edu/research/networking/rocketfuel/
|
||||
*
|
||||
* May 2nd, 2010: Currently only support "weights" file and "cch" file.
|
||||
* http://www.cs.washington.edu/research/networking/rocketfuel/maps/weights-dist.tar.gz
|
||||
* http://www.cs.washington.edu/research/networking/rocketfuel/maps/rocketfuel_maps_cch.tar.gz
|
||||
*/
|
||||
class RocketfuelTopologyReader : public TopologyReader
|
||||
{
|
||||
public:
|
||||
static TypeId GetTypeId (void);
|
||||
|
||||
RocketfuelTopologyReader ();
|
||||
virtual ~RocketfuelTopologyReader ();
|
||||
|
||||
/**
|
||||
* \brief Main topology reading function.
|
||||
*
|
||||
* This method opens an input stream and reads the Rocketfuel-format file.
|
||||
* Every row represents a topology link (the ids of a couple of nodes),
|
||||
* so the input file is read line by line to figure out how many links
|
||||
* and nodes are in the topology.
|
||||
*
|
||||
* \return the container of the nodes created (or empty container if there was an error)
|
||||
*/
|
||||
virtual NodeContainer Read (void);
|
||||
|
||||
private:
|
||||
RocketfuelTopologyReader (const RocketfuelTopologyReader&);
|
||||
RocketfuelTopologyReader& operator= (const RocketfuelTopologyReader&);
|
||||
// Parser for the *.cch file available at:
|
||||
// http://www.cs.washington.edu/research/networking/rocketfuel/maps/rocketfuel_maps_cch.tar.gz
|
||||
NodeContainer GenerateFromMapsFile (int argc, char *argv[]);
|
||||
// Parser for the weights.* file available at:
|
||||
// http://www.cs.washington.edu/research/networking/rocketfuel/maps/weights-dist.tar.gz
|
||||
NodeContainer GenerateFromWeightsFile (int argc, char *argv[]);
|
||||
|
||||
enum RF_FileType
|
||||
{
|
||||
RF_MAPS,
|
||||
RF_WEIGHTS,
|
||||
RF_UNKNOWN
|
||||
};
|
||||
enum RF_FileType GetFileType (const char *);
|
||||
|
||||
// end class RocketfuelTopologyReader
|
||||
};
|
||||
|
||||
// end namespace ns3
|
||||
};
|
||||
|
||||
|
||||
#endif // __ROCKETFUEL_TOPOLOGY_READER_H__
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ def build(bld):
|
||||
'topology-reader.cc',
|
||||
'inet-topology-reader.cc',
|
||||
'orbis-topology-reader.cc',
|
||||
'rocketfuel-topology-reader.cc',
|
||||
]
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers.module = 'topology-read'
|
||||
@@ -13,5 +14,6 @@ def build(bld):
|
||||
'topology-reader.h',
|
||||
'inet-topology-reader.h',
|
||||
'orbis-topology-reader.h',
|
||||
'rocketfuel-topology-reader.h',
|
||||
]
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "ns3/topology-reader-helper.h"
|
||||
#include "ns3/inet-topology-reader.h"
|
||||
#include "ns3/orbis-topology-reader.h"
|
||||
#include "ns3/rocketfuel-topology-reader.h"
|
||||
#include "ns3/log.h"
|
||||
|
||||
namespace ns3 {
|
||||
@@ -65,6 +66,11 @@ TopologyReaderHelper::GetTopologyReader ()
|
||||
NS_LOG_INFO ("Creating Inet formatted data input.");
|
||||
m_inFile = CreateObject<InetTopologyReader> ();
|
||||
}
|
||||
else if (m_fileType == "Rocketfuel")
|
||||
{
|
||||
NS_LOG_INFO ("Creating Rocketfuel formatted data input.");
|
||||
m_inFile = CreateObject<RocketfuelTopologyReader> ();
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_ASSERT_MSG (false, "Wrong (unknown) File Type");
|
||||
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
void SetFileName (const std::string fileName);
|
||||
|
||||
/**
|
||||
* \brief Sets the input file type. Supported file types are "Orbis" and "Inet".
|
||||
* \brief Sets the input file type. Supported file types are "Orbis", "Inet", "Rocketfuel".
|
||||
* \param fileType the input file type.
|
||||
*/
|
||||
void SetFileType (const std::string fileType);
|
||||
|
||||
1
test.py
1
test.py
@@ -133,6 +133,7 @@ example_tests = [
|
||||
("tcp/tcp-star-server", "True", "True"),
|
||||
|
||||
("topology-read/topology-read --input=../../examples/topology-read/Inet_small_toposample.txt", "True", "True"),
|
||||
("topology-read/topology-read --format=Rocketfuel --input=../../examples/topology-read/RocketFuel_toposample_1239_weights.txt", "True", "True"),
|
||||
|
||||
("tunneling/virtual-net-device", "True", "True"),
|
||||
|
||||
|
||||
Reference in New Issue
Block a user