blob: e059bbe3060de56ca4cfb824ebe6d49d339f0068 [file] [log] [blame]
jeraldabrahamf9543a42014-02-11 06:37:34 -07001/**
2 *
jeraldabrahame891ac92014-02-16 11:04:01 -07003 * Copyright (C) 2014 University of Arizona.
jeraldabrahamf9543a42014-02-11 06:37:34 -07004 * @author: Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
5 *
6 */
7
jeraldabrahame891ac92014-02-16 11:04:01 -07008#include <sstream>
9#include <boost/asio.hpp>
10#include <boost/filesystem.hpp>
11
12#include <ndn-cpp-dev/face.hpp>
jeraldabrahamf9543a42014-02-11 06:37:34 -070013#include <ndn-cpp-dev/security/key-chain.hpp>
14
15using namespace ndn;
16
jeraldabraham89a58422014-02-18 14:27:14 -070017class Logger
18{
19public:
20
21 Logger()
22 {
23 logLocation_ = "";
24 }
25
26 void
27 shutdownLogger()
28 {
29 if (logFile_.is_open())
30 {
31 log("Terminating Logging Operations" , true, true);
32 logFile_.close();
33 }
34 }
35
36 static std::string
37 getTimestamp()
38 {
39 boost::posix_time::ptime now;
40 now = boost::posix_time::second_clock::local_time();
41 return to_simple_string(now);
42 }
43
44 void
45 log( std::string logLine, bool printTime, bool printToConsole )
46 {
47 if( logLocation_.length() > 0 )
48 {
49 if (printTime)
50 logFile_ << getTimestamp() << " - ";
51 logFile_ << logLine << std::endl;
52 logFile_.flush();
53 if (printToConsole)
54 {
55 if (printTime)
56 std::cout << getTimestamp() << " - ";
57 std::cout << logLine << std::endl;
58 }
59 }
60 else
61 {
62 if (printTime)
63 std::cout << getTimestamp() << " - ";
64 std::cout << logLine << std::endl;
65 }
66 }
67
68 void
69 initializeLog( std::string instanceId )
70 {
71 char* variableValue = std::getenv("NDN_TRAFFIC_LOGFOLDER");
72 std::string logFilename;
73 logLocation_ = "";
74 if (variableValue != NULL)
75 logLocation_ = variableValue;
76 if (boost::filesystem::exists(boost::filesystem::path(logLocation_)))
77 {
78 if (boost::filesystem::is_directory(boost::filesystem::path(logLocation_)))
79 {
80 logFilename = logLocation_+"/NDNTrafficServer_"+instanceId+".log";
81 logFile_.open(logFilename.c_str(), std::ofstream::out | std::ofstream::trunc);
82 if (logFile_.is_open())
83 std::cout << "Log File Initialized: " << logFilename << std::endl;
84 else
85 {
86 std::cout << "ERROR - Unable To Initialize A Log File At: " << logLocation_ << std::endl
87 << "Using Default Output For Logging." << std::endl;
88 logLocation_ = "";
89 }
90 }
91 else
92 {
93 std::cout << "Environment Variable NDN_TRAFFIC_LOGFOLDER Should Be A Folder." << std::endl
94 << "Using Default Output For Logging." << std::endl;
95 logLocation_ = "";
96 }
97 }
98 else
99 {
100 std::cout << "Environment Variable NDN_TRAFFIC_LOGFOLDER Not Set." << std::endl
101 << "Using Default Output For Logging." << std::endl;
102 logLocation_ = "";
103 }
104 }
105
106private:
107
108 std::string logLocation_;
109 std::ofstream logFile_;
110
111};
112
113
jeraldabrahamf9543a42014-02-11 06:37:34 -0700114class NdnTrafficServer
115{
116public:
117
jeraldabraham89a58422014-02-18 14:27:14 -0700118 NdnTrafficServer( char* programName ) : ioService_(new boost::asio::io_service), face_(ioService_), keyChain_()
jeraldabrahamf9543a42014-02-11 06:37:34 -0700119 {
jeraldabrahame891ac92014-02-16 11:04:01 -0700120 std::srand(std::time(0));
jeraldabraham89a58422014-02-18 14:27:14 -0700121 instanceId_ = toString(std::rand());
jeraldabrahamf9543a42014-02-11 06:37:34 -0700122 programName_ = programName;
123 contentDelayTime_ = getDefaultContentDelayTime();
jeraldabraham89a58422014-02-18 14:27:14 -0700124 totalRegistrationsFailed_ = 0;
jeraldabrahamf9543a42014-02-11 06:37:34 -0700125 configurationFile_ = "";
jeraldabraham89a58422014-02-18 14:27:14 -0700126 totalInterestReceived_ = 0;
jeraldabrahamf9543a42014-02-11 06:37:34 -0700127 }
128
jeraldabraham89a58422014-02-18 14:27:14 -0700129 class DataTrafficConfiguration
jeraldabrahamf9543a42014-02-11 06:37:34 -0700130 {
jeraldabraham89a58422014-02-18 14:27:14 -0700131 public:
132
133 DataTrafficConfiguration()
134 {
135 name = "";
136 contentType = -1;
137 freshnessPeriod = -1;
138 contentBytes = -1;
139 content = "";
140 totalInterestReceived = 0;
141 }
142
143 void
144 printTrafficConfiguration( Logger& logger )
145 {
146 std::string detail;
147 detail = "";
148 if (name != "")
149 detail += "Name="+name+", ";
150 if (contentType >= 0)
151 detail += "ContentType="+toString(contentType)+", ";
152 if (freshnessPeriod >= 0)
153 detail += "FreshnessPeriod="+toString(freshnessPeriod)+", ";
154 if (contentBytes >= 0)
155 detail += "ContentBytes="+toString(contentBytes)+", ";
156 if (content != "")
157 detail += "Content="+content+", ";
158 if (detail.length() >= 0)
159 detail = detail.substr(0, detail.length()-2);
160 logger.log(detail, false, false);
161 }
162
163
164 bool
165 extractParameterValue( std::string detail, std::string& parameter, std::string& value )
166 {
167 int i;
168 std::string allowedCharacters = ":/+._-%";
169 parameter = "";
170 value = "";
171 i = 0;
172 while (detail[i] != '=' && i < detail.length())
173 {
174 parameter += detail[i];
175 i++;
176 }
177 if (i == detail.length())
178 return false;
179 i++;
180 while ((std::isalnum(detail[i]) || allowedCharacters.find(detail[i]) != std::string::npos) && i < detail.length())
181 {
182 value += detail[i];
183 i++;
184 }
185 if(parameter == "" || value == "")
186 return false;
187 return true;
188 }
189
190 bool
191 processConfigurationDetail( std::string detail, Logger& logger, int lineNumber )
192 {
193 std::string parameter, value;
194 if (extractParameterValue(detail, parameter, value))
195 {
196 if (parameter == "Name")
197 name = value;
198 else if (parameter == "ContentType")
199 contentType = toInteger(value);
200 else if (parameter == "FreshnessPeriod")
201 freshnessPeriod = toInteger(value);
202 else if (parameter == "ContentBytes")
203 contentBytes = toInteger(value);
204 else if (parameter == "Content")
205 content = value;
206 else
207 logger.log("Line "+toString(lineNumber)+" \t- Invalid Parameter='"+parameter+"'", false, true);
208 }
209 else
210 {
211 logger.log("Line "+toString(lineNumber)+" \t- Improper Traffic Configuration Line- "+detail, false, true);
212 return false;
213 }
214 return true;
215 }
216
217 bool
218 checkTrafficDetailCorrectness()
219 {
220 return true;
221 }
222
223 std::string name;
224 int contentType;
225 int freshnessPeriod;
226 int contentBytes;
227 std::string content;
228 int totalInterestReceived;
229
230 };
231
232 std::string
233 getDefaultContent()
234 {
235 return "";
236 }
237
238 static std::string
239 toString( int integerValue )
240 {
241 std::stringstream stream;
242 stream << integerValue;
243 return stream.str();
244 }
245
246 static int
247 toInteger( std::string stringValue )
248 {
249 int integerValue;
250 std::stringstream stream(stringValue);
251 stream >> integerValue;
252 return integerValue;
jeraldabrahamf9543a42014-02-11 06:37:34 -0700253 }
254
255 void
256 usage()
257 {
258 std::cout << "\nUsage: " << programName_ << " Printing Usage"
259 "\n\n";
260 exit(1);
261 }
262
263 int
264 getDefaultContentDelayTime()
265 {
266 return 0;
267 }
268
jeraldabrahamf9543a42014-02-11 06:37:34 -0700269 void
270 setContentDelayTime( int contentDelayTime )
271 {
272 if (contentDelayTime < 0)
273 usage();
274 contentDelayTime_ = contentDelayTime;
275 }
276
277 void
jeraldabrahamf9543a42014-02-11 06:37:34 -0700278 setConfigurationFile( char* configurationFile )
279 {
280 configurationFile_ = configurationFile;
281 }
282
jeraldabrahame891ac92014-02-16 11:04:01 -0700283 void
284 signalHandler()
285 {
jeraldabraham89a58422014-02-18 14:27:14 -0700286 logger_.shutdownLogger();
jeraldabrahame891ac92014-02-16 11:04:01 -0700287 face_.shutdown();
288 ioService_.reset();
jeraldabraham89a58422014-02-18 14:27:14 -0700289 logStatistics();
jeraldabrahame891ac92014-02-16 11:04:01 -0700290 exit(1);
291 }
292
293 void
jeraldabraham89a58422014-02-18 14:27:14 -0700294 logStatistics()
jeraldabrahame891ac92014-02-16 11:04:01 -0700295 {
jeraldabraham89a58422014-02-18 14:27:14 -0700296 int patternId;
297 logger_.log("\n\n== Interest Traffic Report ==\n", false, true);
298 logger_.log("Total Traffic Pattern Types = "+toString((int)trafficPattern_.size()), false, true);
299 logger_.log("Total Interests Received = "+toString(totalInterestReceived_), false, true);
300 for (patternId=0; patternId<trafficPattern_.size(); patternId++)
jeraldabrahame891ac92014-02-16 11:04:01 -0700301 {
jeraldabraham89a58422014-02-18 14:27:14 -0700302 logger_.log("\nTraffic Pattern Type #"+toString(patternId+1), false, true);
303 trafficPattern_[patternId].printTrafficConfiguration(logger_);
304 logger_.log("Total Interests Received = "+toString(trafficPattern_[patternId].totalInterestReceived)+"\n", false, true);
305 }
306 }
307
308 bool
309 checkTrafficPatternCorrectness()
310 {
311 return true;
312 }
313
314 void
315 analyzeConfigurationFile()
316 {
317 int patternId;
318 int lineNumber;
319 bool skipLine;
320 std::string patternLine;
321 std::ifstream patternFile;
322 logger_.log("Analyzing Traffic Configuration File: " + configurationFile_, true, true);
323 patternFile.open(configurationFile_.c_str());
324 if (patternFile.is_open())
325 {
326 patternId = 0;
327 lineNumber = 0;
328 while (getline(patternFile, patternLine))
jeraldabrahame891ac92014-02-16 11:04:01 -0700329 {
jeraldabraham89a58422014-02-18 14:27:14 -0700330 lineNumber++;
331 if (std::isalpha(patternLine[0]))
332 {
333 DataTrafficConfiguration dataData;
334 skipLine = false;
335 patternId++;
336 if (dataData.processConfigurationDetail(patternLine, logger_, lineNumber))
337 {
338 while (getline(patternFile, patternLine) && std::isalpha(patternLine[0]))
339 {
340 lineNumber++;
341 if (!dataData.processConfigurationDetail(patternLine, logger_, lineNumber))
342 {
343 skipLine = true;
344 break;
345 }
346 }
347 lineNumber++;
348 }
349 else
350 skipLine = true;
351 if( !skipLine )
352 {
353 if (dataData.checkTrafficDetailCorrectness())
354 trafficPattern_.push_back(dataData);
355 }
356 }
jeraldabrahame891ac92014-02-16 11:04:01 -0700357 }
jeraldabraham89a58422014-02-18 14:27:14 -0700358 patternFile.close();
359 if (!checkTrafficPatternCorrectness())
jeraldabrahame891ac92014-02-16 11:04:01 -0700360 {
jeraldabraham89a58422014-02-18 14:27:14 -0700361 logger_.log("ERROR - Traffic Configuration Provided Is Not Proper- " + configurationFile_, false, true);
362 logger_.shutdownLogger();
363 exit(1);
364 }
365 logger_.log("Traffic Configuration File Processing Completed\n", true, false);
366 for (patternId = 0; patternId < trafficPattern_.size(); patternId++)
367 {
368 logger_.log("Traffic Pattern Type #"+toString(patternId+1), false, false);
369 trafficPattern_[patternId].printTrafficConfiguration(logger_);
370 logger_.log("", false, false);
jeraldabrahame891ac92014-02-16 11:04:01 -0700371 }
372 }
373 else
374 {
jeraldabraham89a58422014-02-18 14:27:14 -0700375 logger_.log("ERROR - Unable To Open Traffic Configuration File: " + configurationFile_, false, true);
376 logger_.shutdownLogger();
377 exit(1);
jeraldabrahame891ac92014-02-16 11:04:01 -0700378 }
379 }
380
381 void
382 initializeTrafficConfiguration()
383 {
jeraldabraham89a58422014-02-18 14:27:14 -0700384 if (boost::filesystem::exists(boost::filesystem::path(configurationFile_)))
385 {
386 if(boost::filesystem::is_regular_file(boost::filesystem::path(configurationFile_)))
387 {
388 analyzeConfigurationFile();
389 }
390 else
391 {
392 logger_.log("ERROR - Traffic Configuration File Is Not A Regular File: " + configurationFile_, false, true);
393 logger_.shutdownLogger();
394 exit(1);
395 }
396 }
397 else
398 {
399 logger_.log("ERROR - Traffic Configuration File Does Not Exist: " + configurationFile_, false, true);
400 logger_.shutdownLogger();
401 exit(1);
402 }
403 }
404
405 static std::string
406 getRandomByteString( int randomSize )
407 {
408 int i;
409 std::string characterSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvw0123456789";
410 std::string randomData;
411 for (i=0; i<randomSize; i++)
412 randomData += characterSet[std::rand() % characterSet.length()];
413 return randomData;
414 }
415
416 void
417 onInterest( const Name& name, const Interest& interest, int patternId )
418 {
419 std::string content, logLine;
420 content = "";
421 logLine = "";
422 Data data(interest.getName());
423 if (trafficPattern_[patternId].contentType >= 0)
424 data.setContentType(trafficPattern_[patternId].contentType);
425 if (trafficPattern_[patternId].freshnessPeriod >= 0)
426 data.setFreshnessPeriod(trafficPattern_[patternId].freshnessPeriod);
427 if (trafficPattern_[patternId].contentBytes >= 0)
428 content = getRandomByteString(trafficPattern_[patternId].contentBytes);
429 if (trafficPattern_[patternId].content != "")
430 content = trafficPattern_[patternId].content;
431 data.setContent((const uint8_t*)content.c_str(), content.length());
432 keyChain_.sign(data);
433 totalInterestReceived_++;
434 trafficPattern_[patternId].totalInterestReceived++;
435 logLine += "Interest Received - PatternID="+toString(patternId);
436 logLine += ", GlobalID="+toString(totalInterestReceived_);
437 logLine += ", LocalID="+toString(trafficPattern_[patternId].totalInterestReceived);
438 logLine += ", Name="+trafficPattern_[patternId].name;
439 logger_.log(logLine, true, false);
440 face_.put(data);
441 }
442
443 void
444 onRegisterFailed( const ndn::Name& prefix, const std::string& reason, int patternId )
445 {
446 std::string logLine;
447 logLine = "";
448 logLine += "Prefix Registration Failed - PatternID="+toString(patternId);
449 logLine += ", Name="+trafficPattern_[patternId].name;
450 logger_.log(logLine, true, true);
451 totalRegistrationsFailed_++;
452 if (totalRegistrationsFailed_ == trafficPattern_.size())
453 signalHandler();
jeraldabrahame891ac92014-02-16 11:04:01 -0700454 }
455
456 void
457 initialize()
458 {
459 boost::asio::signal_set signalSet(*ioService_, SIGINT, SIGTERM);
460 signalSet.async_wait(boost::bind(&NdnTrafficServer::signalHandler, this));
jeraldabraham89a58422014-02-18 14:27:14 -0700461 logger_.initializeLog(instanceId_);
jeraldabrahame891ac92014-02-16 11:04:01 -0700462 initializeTrafficConfiguration();
jeraldabraham89a58422014-02-18 14:27:14 -0700463
464 int patternId;
465 for (patternId=0; patternId<trafficPattern_.size(); patternId++ )
466 {
467 face_.setInterestFilter( trafficPattern_[patternId].name,
468 func_lib::bind( &NdnTrafficServer::onInterest,
469 this, _1, _2,
470 patternId),
471 func_lib::bind( &NdnTrafficServer::onRegisterFailed,
472 this, _1, _2,
473 patternId));
474 }
475
476 try {
477 face_.processEvents();
478 }
479 catch(std::exception &e) {
480 logger_.log("ERROR: "+(std::string)e.what(), true, true);
481 logger_.shutdownLogger();
482 }
jeraldabrahame891ac92014-02-16 11:04:01 -0700483 }
484
jeraldabrahamf9543a42014-02-11 06:37:34 -0700485private:
486
487 KeyChain keyChain_;
488 std::string programName_;
jeraldabraham89a58422014-02-18 14:27:14 -0700489 std::string instanceId_;
jeraldabrahamf9543a42014-02-11 06:37:34 -0700490 int contentDelayTime_;
jeraldabraham89a58422014-02-18 14:27:14 -0700491 int totalRegistrationsFailed_;
492 Logger logger_;
jeraldabrahamf9543a42014-02-11 06:37:34 -0700493 std::string configurationFile_;
jeraldabrahame891ac92014-02-16 11:04:01 -0700494 ptr_lib::shared_ptr<boost::asio::io_service> ioService_;
495 Face face_;
jeraldabraham89a58422014-02-18 14:27:14 -0700496 std::vector<DataTrafficConfiguration> trafficPattern_;
497 int totalInterestReceived_;
jeraldabrahamf9543a42014-02-11 06:37:34 -0700498
499};
500
501int main( int argc, char* argv[] )
502{
503 int option;
504 NdnTrafficServer ndnTrafficServer (argv[0]);
jeraldabrahame891ac92014-02-16 11:04:01 -0700505 while ((option = getopt(argc, argv, "hd:")) != -1) {
jeraldabrahamf9543a42014-02-11 06:37:34 -0700506 switch (option) {
507 case 'h' :
508 ndnTrafficServer.usage();
509 break;
510 case 'd' :
511 ndnTrafficServer.setContentDelayTime(atoi(optarg));
512 break;
jeraldabrahamf9543a42014-02-11 06:37:34 -0700513 default :
514 ndnTrafficServer.usage();
515 break;
516 }
517 }
518
519 argc -= optind;
520 argv += optind;
521
jeraldabrahame891ac92014-02-16 11:04:01 -0700522 if (argv[0] == NULL)
jeraldabrahamf9543a42014-02-11 06:37:34 -0700523 ndnTrafficServer.usage();
524
525 ndnTrafficServer.setConfigurationFile(argv[0]);
jeraldabrahame891ac92014-02-16 11:04:01 -0700526 ndnTrafficServer.initialize();
jeraldabrahamf9543a42014-02-11 06:37:34 -0700527
528 return 0;
529}