security: Cleaning up all security stuff...

This commit is contained in:
Yingdi Yu committed 2014-02-03 10:41:11 -08:00
1 parent 6d638f0355
commit 280bb9652f
20 files changed
+533 -1447

No files matched your search

-440
View File
@@ -1,440 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2013, Regents of the University of California
* Yingdi Yu
*
* BSD license, See the LICENSE file for more information
*
* Author: Yingdi Yu <yingdi@cs.ucla.edu>
*/
#include "sync-intro-certificate.h"
#include "sync-logging.h"
#include <ndn-cpp-dev/security/verifier.hpp>
#include <ndn-cpp-dev/security/signature-sha256-with-rsa.hpp>
#include "sec-policy-sync.h"
using namespace ndn;
using namespace ndn::ptr_lib;
using namespace std;
INIT_LOGGER("SecPolicySync");
SecPolicySync::SecPolicySync(const Name& signingIdentity,
const Name& signingCertificateName,
const Name& syncPrefix,
shared_ptr<Face> face,
int stepLimit)
: m_signingIdentity(signingIdentity)
, m_signingCertificateName(signingCertificateName.getPrefix(signingCertificateName.size()-1))
, m_syncPrefix(syncPrefix)
, m_stepLimit(stepLimit)
, m_keyChain(new KeyChain())
{
m_introCertPrefix = syncPrefix;
m_introCertPrefix.append("WOT");
m_syncDataPolicy = make_shared<SecRuleRelative>("^[^<%F0\\.>]*<%F0\\.>([^<chronos>]*)<chronos><>",
"^([^<KEY>]*)<KEY>(<>*)[<dsk-.*><ksk-.*>]<ID-CERT>$",
"==", "\\1", "\\1", true);
}
SecPolicySync::~SecPolicySync()
{}
bool
SecPolicySync::skipVerifyAndTrust (const Data& data)
{ return false; }
bool
SecPolicySync::requireVerify (const Data& data)
{ return true; }
shared_ptr<ValidationRequest>
SecPolicySync::checkVerificationPolicy(const shared_ptr<Data>& data,
int stepCount,
const OnVerified& onVerified,
const OnVerifyFailed& onVerifyFailed)
{
if(stepCount > m_stepLimit)
{
onVerifyFailed(data);
return shared_ptr<ValidationRequest>();
}
try{
SignatureSha256WithRsa sig(data->getSignature());
const Name& keyLocatorName = sig.getKeyLocator().getName();
// if data is intro cert
if(m_introCertPrefix.isPrefixOf(data->getName()))
{
Name keyName = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);
map<Name, PublicKey>::const_iterator it = m_trustedIntroducers.find(keyName);
if(m_trustedIntroducers.end() != it)
{
if(Verifier::verifySignature(*data, sig, it->second))
onVerified(data);
else
onVerifyFailed(data);
return shared_ptr<ValidationRequest>();
}
else
return prepareRequest(keyName, true, data, stepCount, onVerified, onVerifyFailed);
}
// if data is diff data or sync data
if(m_syncPrefix.isPrefixOf(data->getName()) || m_syncDataPolicy->satisfy(*data))
{
Name keyName = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);
map<Name, PublicKey>::const_iterator it = m_trustedIntroducers.find(keyName);
if(m_trustedIntroducers.end() != it)
{
if(Verifier::verifySignature(*data, sig, it->second))
onVerified(data);
else
onVerifyFailed(data);
return shared_ptr<ValidationRequest>();
}
it = m_trustedProducers.find(keyName);
if(m_trustedProducers.end() != it)
{
if(Verifier::verifySignature(*data, sig, it->second))
onVerified(data);
else
onVerifyFailed(data);
return shared_ptr<ValidationRequest>();
}
return prepareRequest(keyName, false, data, stepCount, onVerified, onVerifyFailed);
}
}catch(SignatureSha256WithRsa::Error &e){
_LOG_DEBUG("SecPolicySync Error: " << e.what());
onVerifyFailed(data);
return shared_ptr<ValidationRequest>();
}catch(KeyLocator::Error &e){
_LOG_DEBUG("SecPolicySync Error: " << e.what());
onVerifyFailed(data);
return shared_ptr<ValidationRequest>();
}
onVerifyFailed(data);
return shared_ptr<ValidationRequest>();
}
bool
SecPolicySync::checkSigningPolicy(const Name& dataName,
const Name& certificateName)
{
return true;
}
Name
SecPolicySync::inferSigningIdentity(const ndn::Name& dataName)
{ return m_signingIdentity; }
void
SecPolicySync::addTrustAnchor(const IdentityCertificate& identityCertificate, bool isIntroducer)
{
Name publicKeyName = identityCertificate.getPublicKeyName();
_LOG_DEBUG("Add intro/producer: " << publicKeyName);
if(isIntroducer)
m_trustedIntroducers[publicKeyName] = identityCertificate.getPublicKeyInfo();
else
m_trustedProducers[publicKeyName] = identityCertificate.getPublicKeyInfo();
}
void
SecPolicySync::addSyncDataRule(const Name& prefix,
const IdentityCertificate& identityCertificate,
bool isIntroducer)
{ addTrustAnchor(identityCertificate, isIntroducer); }
shared_ptr<const vector<Name> >
SecPolicySync::getAllIntroducerName()
{
shared_ptr<vector<Name> > nameList = make_shared<vector<Name> >();
map<Name, PublicKey>::iterator it = m_trustedIntroducers.begin();
for(; it != m_trustedIntroducers.end(); it++)
nameList->push_back(it->first);
return nameList;
}
shared_ptr<ValidationRequest>
SecPolicySync::prepareRequest(const Name& keyName,
bool forIntroducer,
shared_ptr<Data> data,
const int & stepCount,
const OnVerified& onVerified,
const OnVerifyFailed& onVerifyFailed)
{
Name interestPrefix = m_syncPrefix;
interestPrefix.append("WOT").append(keyName.wireEncode()).append("INTRO-CERT");
shared_ptr<const vector<Name> > nameList = getAllIntroducerName();
if(0 == nameList->size())
{
onVerifyFailed(data);
return shared_ptr<ValidationRequest>();
}
Name interestName = interestPrefix;
interestName.append(nameList->at(0).wireEncode());
if(forIntroducer)
interestName.append("INTRODUCER");
shared_ptr<ndn::Interest> interest = make_shared<ndn::Interest>(interestName);
OnVerified introCertVerified = func_lib::bind(&SecPolicySync::onIntroCertVerified,
this,
_1,
forIntroducer,
data,
onVerified,
onVerifyFailed);
OnVerifyFailed introCertVerifyFailed = func_lib::bind(&SecPolicySync::onIntroCertVerifyFailed,
this,
_1,
interestPrefix,
forIntroducer,
nameList,
1,
data,
onVerified,
onVerifyFailed);
shared_ptr<ValidationRequest> nextStep = make_shared<ValidationRequest>(interest,
introCertVerified,
introCertVerifyFailed,
1,
m_stepLimit-1);
return nextStep;
}
void
SecPolicySync::OnIntroCertInterest(const shared_ptr<const Name>& prefix,
const shared_ptr<const ndn::Interest>& interest,
Transport& transport,
uint64_t registeredPrefixId)
{
map<Name, Data>::const_iterator it = m_introCert.find(*prefix);
if(m_introCert.end() != it)
m_face->put(it->second);
}
void
SecPolicySync::OnIntroCertRegisterFailed(const shared_ptr<const Name>& prefix)
{
}
void
SecPolicySync::onIntroCertVerified(const shared_ptr<Data>& introCertificateData,
bool forIntroducer,
shared_ptr<Data> originalData,
const OnVerified& onVerified,
const OnVerifyFailed& onVerifyFailed)
{
shared_ptr<SyncIntroCertificate> introCertificate = make_shared<SyncIntroCertificate>(*introCertificateData);
Name subjectKeyName = introCertificate->getPublicKeyName();
if(forIntroducer)
{
//Add the intro cert subject as trusted introducer.
m_trustedIntroducers[subjectKeyName] = introCertificate->getPublicKeyInfo();
//Generate another intro cert for the cert subject.
SyncIntroCertificate syncIntroCertificate(m_syncPrefix,
subjectKeyName,
m_keyChain->getDefaultKeyNameForIdentity(m_signingIdentity),
introCertificate->getNotBefore(),
introCertificate->getNotAfter(),
introCertificate->getPublicKeyInfo(),
SyncIntroCertificate::INTRODUCER);
m_keyChain->signByIdentity(syncIntroCertificate, m_signingIdentity);
m_face->put(syncIntroCertificate);
// Name prefix = syncIntroCertificate.getName().getPrefix(syncIntroCertificate.getName().size()-1);
// map<string, Data>::const_iterator it = m_introCert.find(prefix);
// if(m_introCert.end() != it)
// {
// it->second = syncIntroCertificate;
// }
// else
// {
// m_introCert.insert(pair <Name, Data> (prefix, syncIntroCertificate));
// m_face->registerPrefix(prefix,
// boost::bind(&SecPolicySync::onIntroCertInterest, this, _1, _2, _3, _4),
// boost::bind(&SecPolicySync::onIntroCertRegisterFailed, this, _1));
// }
}
else
{
//Add the intro cert subject as trusted producer.
m_trustedProducers[subjectKeyName] = introCertificate->getPublicKeyInfo();
//Generate another intro cert for the cert subject.
SyncIntroCertificate syncIntroCertificate(m_syncPrefix,
subjectKeyName,
m_keyChain->getDefaultKeyNameForIdentity(m_signingIdentity),
introCertificate->getNotBefore(),
introCertificate->getNotAfter(),
introCertificate->getPublicKeyInfo(),
SyncIntroCertificate::PRODUCER);
m_keyChain->signByIdentity(syncIntroCertificate, m_signingIdentity);
m_face->put(syncIntroCertificate);
// Name prefix = syncIntroCertificate.getName().getPrefix(syncIntroCertificate.getName().size()-1);
// map<string, Data>::const_iterator it = m_introCert.find(prefix);
// if(m_introCert.end() != it)
// {
// it->second = syncIntroCertificate;
// }
// else
// {
// m_introCert.insert(pair <Name, Data> (prefix, syncIntroCertificate));
// m_face->registerPrefix(prefix,
// boost::bind(&SecPolicySync::onIntroCertInterest, this, _1, _2, _3, _4),
// boost::bind(&SecPolicySync::onIntroCertRegisterFailed, this, _1));
// }
}
try{
SignatureSha256WithRsa sig(originalData->getSignature());
if(Verifier::verifySignature(*originalData, sig, introCertificate->getPublicKeyInfo()))
onVerified(originalData);
else
onVerifyFailed(originalData);
}catch(SignatureSha256WithRsa::Error &e){
onVerifyFailed(originalData);
}catch(KeyLocator::Error &e){
onVerifyFailed(originalData);
}
}
void
SecPolicySync::onIntroCertVerifyFailed(const shared_ptr<Data>& introCertificateData,
Name interestPrefix,
bool forIntroducer,
shared_ptr<const vector<Name> > introNameList,
int nextIntroducerIndex,
shared_ptr<Data> originalData,
const OnVerified& onVerified,
const OnVerifyFailed& onVerifyFailed)
{
Name interestName = interestPrefix;
if(nextIntroducerIndex < introNameList->size())
interestName.append(introNameList->at(nextIntroducerIndex).wireEncode());
else
onVerifyFailed(originalData);
if(forIntroducer)
interestName.append("INTRODUCER");
ndn::Interest interest(interestName);
OnVerified introCertVerified = func_lib::bind(&SecPolicySync::onIntroCertVerified,
this,
_1,
forIntroducer,
originalData,
onVerified,
onVerifyFailed);
OnVerifyFailed introCertVerifyFailed = func_lib::bind(&SecPolicySync::onIntroCertVerifyFailed,
this,
_1,
interestPrefix,
forIntroducer,
introNameList,
nextIntroducerIndex + 1,
originalData,
onVerified,
onVerifyFailed);
m_face->expressInterest(interest,
func_lib::bind(&SecPolicySync::onIntroCertData,
this,
_1,
_2,
m_stepLimit-1,
introCertVerified,
introCertVerifyFailed),
func_lib::bind(&SecPolicySync::onIntroCertTimeout,
this,
_1,
1,
m_stepLimit-1,
introCertVerified,
introCertVerifyFailed)
);
}
void
SecPolicySync::onIntroCertData(const shared_ptr<const ndn::Interest> &interest,
const shared_ptr<Data>& introCertificateData,
int stepCount,
const OnVerified& introCertVerified,
const OnVerifyFailed& introCertVerifyFailed)
{
shared_ptr<ValidationRequest> nextStep = checkVerificationPolicy(introCertificateData, stepCount, introCertVerified, introCertVerifyFailed);
if (nextStep)
m_face->expressInterest(*nextStep->interest_,
func_lib::bind(&SecPolicySync::onIntroCertData,
this,
_1,
_2,
nextStep->stepCount_,
nextStep->onVerified_,
nextStep->onVerifyFailed_),
func_lib::bind(&SecPolicySync::onIntroCertTimeout,
this,
_1,
nextStep->retry_,
nextStep->stepCount_,
nextStep->onVerified_,
nextStep->onVerifyFailed_)
);
}
void
SecPolicySync::onIntroCertTimeout(const shared_ptr<const ndn::Interest>& interest,
int retry,
int stepCount,
const OnVerified& introCertVerified,
const OnVerifyFailed& introCertVerifyFailed)
{
if(retry > 0)
m_face->expressInterest(*interest,
func_lib::bind(&SecPolicySync::onIntroCertData,
this,
_1,
_2,
stepCount,
introCertVerified,
introCertVerifyFailed),
func_lib::bind(&SecPolicySync::onIntroCertTimeout,
this,
_1,
retry - 1,
stepCount,
introCertVerified,
introCertVerifyFailed)
);
else
introCertVerifyFailed(shared_ptr<Data>());
}
-141
View File
@@ -1,141 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2013, Regents of the University of California
* Yingdi Yu
*
* BSD license, See the LICENSE file for more information
*
* Author: Yingdi Yu <yingdi@cs.ucla.edu>
*/
#ifndef SEC_POLICY_SYNC_H
#define SEC_POLICY_SYNC_H
#include <ndn-cpp-dev/face.hpp>
#include <ndn-cpp-dev/security/key-chain.hpp>
#include <ndn-cpp-dev/security/verifier.hpp>
#include <ndn-cpp-dev/security/sec-policy.hpp>
#include <ndn-cpp-dev/security/identity-certificate.hpp>
#include <ndn-cpp-et/policy/sec-rule-relative.hpp>
// #include <ndn-cpp-et/policy/sec-rule-specific.hpp>
#include <map>
class SecPolicySync : public ndn::SecPolicy
{
public:
SecPolicySync(const ndn::Name& signingIdentity,
const ndn::Name& signingCertificateName,
const ndn::Name& syncPrefix,
ndn::ptr_lib::shared_ptr<ndn::Face> face,
int m_stepLimit = 3);
virtual
~SecPolicySync();
bool
skipVerifyAndTrust (const ndn::Data& data);
bool
requireVerify (const ndn::Data& data);
ndn::ptr_lib::shared_ptr<ndn::ValidationRequest>
checkVerificationPolicy(const ndn::ptr_lib::shared_ptr<ndn::Data>& data,
int stepCount,
const ndn::OnVerified& onVerified,
const ndn::OnVerifyFailed& onVerifyFailed);
bool
checkSigningPolicy(const ndn::Name& dataName,
const ndn::Name& certificateName);
ndn::Name
inferSigningIdentity(const ndn::Name& dataName);
void
addTrustAnchor(const ndn::IdentityCertificate& identityCertificate, bool isIntroducer);
void
addSyncDataRule(const ndn::Name& prefix,
const ndn::IdentityCertificate& identityCertificate,
bool isIntroducer);
private:
ndn::ptr_lib::shared_ptr<ndn::ValidationRequest>
prepareIntroducerRequest(const ndn::Name& keyName,
ndn::ptr_lib::shared_ptr<ndn::Data> data,
const int & stepCount,
const ndn::OnVerified& onVerified,
const ndn::OnVerifyFailed& onVerifyFailed);
ndn::ptr_lib::shared_ptr<const std::vector<ndn::Name> >
getAllIntroducerName();
ndn::ptr_lib::shared_ptr<ndn::ValidationRequest>
prepareRequest(const ndn::Name& keyName,
bool forIntroducer,
ndn::ptr_lib::shared_ptr<ndn::Data> data,
const int & stepCount,
const ndn::OnVerified& onVerified,
const ndn::OnVerifyFailed& onVerifyFailed);
void
OnIntroCertInterest(const ndn::ptr_lib::shared_ptr<const ndn::Name>& prefix,
const ndn::ptr_lib::shared_ptr<const ndn::Interest>& interest,
ndn::Transport& transport,
uint64_t registeredPrefixId);
void
OnIntroCertRegisterFailed(const ndn::ptr_lib::shared_ptr<const ndn::Name>& prefix);
void
onIntroCertVerified(const ndn::ptr_lib::shared_ptr<ndn::Data>& introCertificateData,
bool forIntroducer,
ndn::ptr_lib::shared_ptr<ndn::Data> originalData,
const ndn::OnVerified& onVerified,
const ndn::OnVerifyFailed& onVerifyFailed);
void
onIntroCertVerifyFailed(const ndn::ptr_lib::shared_ptr<ndn::Data>& introCertificateData,
ndn::Name interestPrefix,
bool forIntroducer,
ndn::ptr_lib::shared_ptr<const std::vector<ndn::Name> > introNameList,
int nextIntroducerIndex,
ndn::ptr_lib::shared_ptr<ndn::Data> originalData,
const ndn::OnVerified& onVerified,
const ndn::OnVerifyFailed& onVerifyFailed);
void
onIntroCertData(const ndn::ptr_lib::shared_ptr<const ndn::Interest> &interest,
const ndn::ptr_lib::shared_ptr<ndn::Data>& introCertificateData,
int stepCount,
const ndn::OnVerified& introCertVerified,
const ndn::OnVerifyFailed& introCertVerifyFailed);
void
onIntroCertTimeout(const ndn::ptr_lib::shared_ptr<const ndn::Interest>& interest,
int retry,
int stepCount,
const ndn::OnVerified& introCertVerified,
const ndn::OnVerifyFailed& introCertVerifyFailed);
private:
ndn::Name m_signingIdentity;
ndn::Name m_signingCertificateName;
ndn::Name m_syncPrefix;
ndn::Name m_introCertPrefix;
int m_stepLimit;
ndn::ptr_lib::shared_ptr<ndn::SecRuleRelative> m_syncDataPolicy;
std::map<ndn::Name, ndn::PublicKey> m_trustedIntroducers;
std::map<ndn::Name, ndn::PublicKey> m_trustedProducers;
// std::map<ndn::Name, SecRuleSyncSpecific> m_chatDataRules;
std::map<ndn::Name, ndn::Data> m_introCert;
ndn::ptr_lib::shared_ptr<ndn::KeyChain> m_keyChain;
ndn::ptr_lib::shared_ptr<ndn::Face> m_face;
};
#endif
+5 -5
View File
@@ -103,11 +103,11 @@ public:
operator << (const std::string &str);
/**
* @brief Add uint32_t value to digest calculation
* @param value uint32_t value to put into digest
* @brief Add uint64_t value to digest calculation
* @param value uint64_t value to put into digest
*/
inline Digest &
operator << (uint32_t value);
operator << (uint64_t value);
/**
* @brief Checks if the stored hash is zero-root hash
@@ -153,9 +153,9 @@ Digest::operator << (const std::string &str)
}
inline Digest &
Digest::operator << (uint32_t value)
Digest::operator << (uint64_t value)
{
update (reinterpret_cast<const uint8_t*> (&value), sizeof (uint32_t));
update (reinterpret_cast<const uint8_t*> (&value), sizeof (uint64_t));
return *this;
}
-146
View File
@@ -1,146 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2013, Regents of the University of California
* Yingdi Yu
*
* BSD license, See the LICENSE file for more information
*
* Author: Yingdi Yu <yingdi@cs.ucla.edu>
*/
#include "sync-intro-certificate.h"
using namespace ndn;
using namespace std;
using namespace boost;
SyncIntroCertificate::SyncIntroCertificate ()
: Certificate()
{}
SyncIntroCertificate::SyncIntroCertificate (const Name& nameSpace,
const Name& keyName,
const Name& signerName,
const MillisecondsSince1970& notBefore,
const MillisecondsSince1970& notAfter,
const PublicKey& key,
const IntroType& introType)
: m_nameSpace(nameSpace)
, m_keyName(keyName)
, m_introType(introType)
{
Name certificateName = nameSpace;
certificateName.append("WOT").append(keyName.wireEncode()).append("INTRO-CERT").append(signerName.wireEncode());
switch(introType)
{
case PRODUCER:
certificateName.append("PRODUCER");
break;
case INTRODUCER:
certificateName.append("INTRODUCER");
break;
default:
throw Error("Wrong Introduction Type!");
}
certificateName.appendVersion();
Data::setName(certificateName);
setNotBefore(notBefore);
setNotAfter(notAfter);
setPublicKeyInfo(key);
addSubjectDescription(CertificateSubjectDescription("2.5.4.41", keyName.toUri()));
encode();
}
SyncIntroCertificate::SyncIntroCertificate (const Name& nameSpace,
const IdentityCertificate& identityCertificate,
const Name& signerName,
const IntroType& introType)
: m_nameSpace(nameSpace)
, m_introType(introType)
{
m_keyName = identityCertificate.getPublicKeyName();
Name certificateName = nameSpace;
certificateName.append("WOT").append(m_keyName.wireEncode()).append("INTRO-CERT").append(signerName.wireEncode());
switch(introType)
{
case PRODUCER:
certificateName.append("PRODUCER");
break;
case INTRODUCER:
certificateName.append("INTRODUCER");
break;
default:
throw Error("Wrong Introduction Type!");
}
certificateName.appendVersion();
Data::setName(certificateName);
setNotBefore(identityCertificate.getNotBefore());
setNotAfter(identityCertificate.getNotAfter());
setPublicKeyInfo(identityCertificate.getPublicKeyInfo());
addSubjectDescription(CertificateSubjectDescription("2.5.4.41", m_keyName.toUri()));
}
SyncIntroCertificate::SyncIntroCertificate (const Data& data)
: Certificate(data)
{ setName(getName()); }
SyncIntroCertificate::SyncIntroCertificate (const SyncIntroCertificate& chronosIntroCertificate)
: Certificate(chronosIntroCertificate)
, m_nameSpace(chronosIntroCertificate.m_nameSpace)
, m_keyName(chronosIntroCertificate.m_keyName)
, m_introType(chronosIntroCertificate.m_introType)
{}
Data &
SyncIntroCertificate::setName (const Name& certificateName)
{
int nameLength = certificateName.size();
if(nameLength < 6)
throw Error("Wrong SyncIntroCertificate Name!");
m_nameSpace = certificateName.getPrefix(-6);
if(!certificateName.get(-6).equals("WOT"))
throw Error("Wrong SyncIntroCertificate Name!");
m_keyName.wireDecode(Block(certificateName.get(-5).getValue().buf(),
certificateName.get(-5).getValue().size()));
if(!certificateName.get(-4).equals("INTRO-CERT"))
throw Error("Wrong SyncIntroCertificate Name!");
if(certificateName.get(-2).equals("PRODUCER"))
m_introType = PRODUCER;
else if(certificateName.get(-2).equals("INTRODUCER"))
m_introType = INTRODUCER;
else
throw Error("Wrong SyncIntroCertificate Name!");
return *this;
}
bool
SyncIntroCertificate::isSyncIntroCertificate(const Certificate& certificate)
{
const Name& certificateName = certificate.getName();
int nameLength = certificateName.size();
if(nameLength < 6)
return false;
if(!certificateName.get(-6).equals("WOT"))
return false;
if(!certificateName.get(-4).equals("INTRO-CERT"))
return false;
if(!certificateName.get(-2).equals("PRODUCER") && !certificateName.get(-2).equals("INTRODUCER"))
return false;
return true;
}
-85
View File
@@ -1,85 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2013, Regents of the University of California
* Yingdi Yu
*
* BSD license, See the LICENSE file for more information
*
* Author: Yingdi Yu <yingdi@cs.ucla.edu>
*/
#ifndef SYNC_INTRO_CERTIFICATE_H
#define SYNC_INTRO_CERTIFICATE_H
#include <ndn-cpp-dev/security/certificate.hpp>
#include <ndn-cpp-dev/security/identity-certificate.hpp>
class SyncIntroCertificate : public ndn::Certificate
{
public:
struct Error : public ndn::Certificate::Error { Error(const std::string &what) : ndn::Certificate::Error(what) {} };
enum IntroType{
PRODUCER,
INTRODUCER
};
public:
SyncIntroCertificate ();
SyncIntroCertificate (const ndn::Name& nameSpace,
const ndn::Name& keyName,
const ndn::Name& signerName,
const ndn::MillisecondsSince1970& notBefore,
const ndn::MillisecondsSince1970& notAfter,
const ndn::PublicKey& key,
const IntroType& introType = PRODUCER);
SyncIntroCertificate (const ndn::Name& nameSpace,
const ndn::IdentityCertificate& identityCertificate,
const ndn::Name& signerName,
const IntroType& introType);
SyncIntroCertificate (const ndn::Data& data);
SyncIntroCertificate (const SyncIntroCertificate& chronosIntroCertificate);
virtual
~SyncIntroCertificate ()
{}
ndn::Data&
setName (const ndn::Name& name);
inline const ndn::Name &
getPublicKeyName() const;
inline IntroType
getIntroType();
inline const ndn::Name &
getNameSpace() const;
static bool
isSyncIntroCertificate(const ndn::Certificate& certificate);
protected:
ndn::Name m_nameSpace;
ndn::Name m_keyName;
IntroType m_introType;
};
SyncIntroCertificate::IntroType
SyncIntroCertificate::getIntroType()
{ return m_introType; }
const ndn::Name &
SyncIntroCertificate::getPublicKeyName () const
{ return m_keyName; }
const ndn::Name &
SyncIntroCertificate::getNameSpace() const
{ return m_nameSpace; }
#endif
+69 -101
View File
@@ -39,8 +39,6 @@
using namespace std;
using namespace ndn;
using namespace ndn::ptr_lib;
using namespace ndn::func_lib;
INIT_LOGGER ("SyncLogic");
@@ -61,7 +59,7 @@ namespace Sync
{
SyncLogic::SyncLogic (const Name& syncPrefix,
shared_ptr<SecPolicySync> policy,
shared_ptr<Validator> validator,
shared_ptr<Face> face,
LogicUpdateCallback onUpdate,
LogicRemoveCallback onRemove)
@@ -71,14 +69,14 @@ namespace Sync
, m_onUpdate (onUpdate)
, m_onRemove (onRemove)
, m_perBranch (false)
, m_policy(policy)
, m_verifier(new Verifier(policy))
, m_validator(validator)
, m_keyChain(new KeyChain())
, m_face(face)
, m_scheduler(*face->ioService())
#ifndef NS3_MODULE
, m_randomGenerator (static_cast<unsigned int> (std::time (0)))
, m_rangeUniformRandom (m_randomGenerator, uniform_int<> (200,1000))
, m_reexpressionJitter (m_randomGenerator, uniform_int<> (100,500))
, m_rangeUniformRandom (m_randomGenerator, boost::uniform_int<> (200,1000))
, m_reexpressionJitter (m_randomGenerator, boost::uniform_int<> (100,500))
#else
, m_rangeUniformRandom (200,1000)
, m_reexpressionJitter (10,500)
@@ -88,19 +86,18 @@ namespace Sync
#ifndef NS3_MODULE
// In NS3 module these functions are moved to StartApplication method
m_syncRegisteredPrefixId = m_face->setInterestFilter(m_syncPrefix,
func_lib::bind(&SyncLogic::onSyncInterest, this, _1, _2, _3, _4),
func_lib::bind(&SyncLogic::onSyncRegisterFailed, this, _1));
m_syncRegisteredPrefixId = m_face->setInterestFilter (m_syncPrefix,
bind(&SyncLogic::onSyncInterest, this, _1, _2),
bind(&SyncLogic::onSyncRegisterFailed, this, _1));
m_scheduler.schedule (TIME_SECONDS (0), // no need to add jitter
func_lib::bind (&SyncLogic::sendSyncInterest, this),
REEXPRESSING_INTEREST);
m_reexpressingInterestId = m_scheduler.scheduleEvent (time::seconds (0), // no need to add jitter
bind (&SyncLogic::sendSyncInterest, this));
#endif
}
SyncLogic::SyncLogic (const Name& syncPrefix,
shared_ptr<SecPolicySync> policy,
shared_ptr<Validator> validator,
shared_ptr<Face> face,
LogicPerBranchCallback onUpdateBranch)
: m_state (new FullState)
@@ -108,14 +105,14 @@ SyncLogic::SyncLogic (const Name& syncPrefix,
, m_syncPrefix (syncPrefix)
, m_onUpdateBranch (onUpdateBranch)
, m_perBranch(true)
, m_policy(policy)
, m_verifier(new Verifier(policy))
, m_validator(validator)
, m_keyChain(new KeyChain())
, m_face(face)
, m_scheduler(*face->ioService())
#ifndef NS3_MODULE
, m_randomGenerator (static_cast<unsigned int> (std::time (0)))
, m_rangeUniformRandom (m_randomGenerator, uniform_int<> (200,1000))
, m_reexpressionJitter (m_randomGenerator, uniform_int<> (100,500))
, m_rangeUniformRandom (m_randomGenerator, boost::uniform_int<> (200,1000))
, m_reexpressionJitter (m_randomGenerator, boost::uniform_int<> (100,500))
#else
, m_rangeUniformRandom (200,1000)
, m_reexpressionJitter (10,500)
@@ -125,19 +122,18 @@ SyncLogic::SyncLogic (const Name& syncPrefix,
#ifndef NS3_MODULE
// In NS3 module these functions are moved to StartApplication method
m_syncRegisteredPrefixId = m_face->setInterestFilter(m_syncPrefix,
func_lib::bind(&SyncLogic::onSyncInterest, this, _1, _2, _3, _4),
func_lib::bind(&SyncLogic::onSyncRegisterFailed, this, _1));
m_syncRegisteredPrefixId = m_face->setInterestFilter (m_syncPrefix,
bind(&SyncLogic::onSyncInterest, this, _1, _2),
bind(&SyncLogic::onSyncRegisterFailed, this, _1));
m_scheduler.schedule (TIME_SECONDS (0), // no need to add jitter
func_lib::bind (&SyncLogic::sendSyncInterest, this),
REEXPRESSING_INTEREST);
m_reexpressingInterestId = m_scheduler.scheduleEvent (time::seconds (0), // no need to add jitter
bind (&SyncLogic::sendSyncInterest, this));
#endif
}
SyncLogic::~SyncLogic ()
{
m_face->unsetInterestFilter(m_syncRegisteredPrefixId);
{
// m_face->unsetInterestFilter(m_syncRegisteredPrefixId);
}
#ifdef NS3_MODULE
@@ -169,8 +165,8 @@ void
SyncLogic::stop()
{
m_face->unsetInterestFilter(m_syncRegisteredPrefixId);
m_scheduler.cancel (REEXPRESSING_INTEREST);
m_scheduler.cancel (DELAYED_INTEREST_PROCESSING);
m_scheduler.cancelEvent (m_reexpressingInterestId);
m_scheduler.cancelEvent (m_delayedInterestProcessingId);
}
/**
@@ -207,9 +203,7 @@ SyncLogic::convertNameToDigestAndType (const Name &name)
void
SyncLogic::onSyncInterest (const shared_ptr<const Name>& prefix,
const shared_ptr<const ndn::Interest>& interest,
Transport& transport,
uint64_t registeredPrefixId)
const shared_ptr<const ndn::Interest>& interest)
{
Name name = interest->getName();
@@ -249,46 +243,24 @@ SyncLogic::onSyncRegisterFailed(const shared_ptr<const Name>& prefix)
void
SyncLogic::onSyncData(const shared_ptr<const ndn::Interest>& interest,
const shared_ptr<Data>& data,
const OnVerified& onVerified,
const OnVerifyFailed& onVerifyFailed)
{
m_verifier->verifyData(data, onVerified, onVerifyFailed);
const OnDataValidated& onValidated,
const OnDataValidationFailed& onValidationFailed)
{ m_validator->validate(data, onValidated, onValidationFailed); }
void
SyncLogic::onSyncTimeout(const shared_ptr<const ndn::Interest>& interest)
{
// It is OK. Others will handle the time out situation.
}
void
SyncLogic::onSyncDataTimeout(const shared_ptr<const ndn::Interest>& interest,
int retry,
const OnVerified& onVerified,
const OnVerifyFailed& onVerifyFailed)
{
if(retry > 0)
{
m_face->expressInterest(*interest,
func_lib::bind(&SyncLogic::onSyncData,
this,
_1,
_2,
onVerified,
onVerifyFailed),
func_lib::bind(&SyncLogic::onSyncDataTimeout,
this,
_1,
retry - 1,
onVerified,
onVerifyFailed));
}
else
_LOG_DEBUG("Sync interest eventually times out!");
}
void
SyncLogic::onSyncDataVerifyFailed(const shared_ptr<Data>& data)
SyncLogic::onSyncDataValidationFailed(const shared_ptr<const Data>& data)
{
_LOG_DEBUG("Sync data cannot be verified!");
}
void
SyncLogic::onSyncDataVerified(const shared_ptr<Data>& data)
SyncLogic::onSyncDataValidated(const shared_ptr<const Data>& data)
{
Name name = data->getName();
const char* wireData = (const char*)data->getContent().value();
@@ -309,7 +281,7 @@ SyncLogic::onSyncDataVerified(const shared_ptr<Data>& data)
else
{
// timer is always restarted when we schedule recovery
m_scheduler.cancel (REEXPRESSING_RECOVERY_INTEREST);
m_scheduler.cancelEvent (m_reexpressingRecoveryInterestId);
processSyncData (name, digest, wireData, len);
}
}
@@ -367,15 +339,14 @@ SyncLogic::processSyncInterest (const Name &name, DigestConstPtr digest, bool ti
if (exists) // somebody else replied, so restart random-game timer
{
_LOG_DEBUG ("Unknown digest, but somebody may have already replied, so restart our timer");
m_scheduler.cancel (DELAYED_INTEREST_PROCESSING);
m_scheduler.cancelEvent (m_delayedInterestProcessingId);
}
uint32_t waitDelay = GET_RANDOM (m_rangeUniformRandom);
_LOG_DEBUG ("Digest is not in the log. Schedule processing after small delay: " << waitDelay << "ms");
m_scheduler.schedule (TIME_MILLISECONDS (waitDelay),
func_lib::bind (&SyncLogic::processSyncInterest, this, name, digest, true),
DELAYED_INTEREST_PROCESSING);
m_delayedInterestProcessingId = m_scheduler.scheduleEvent (time::milliseconds (waitDelay),
bind (&SyncLogic::processSyncInterest, this, name, digest, true));
}
else
{
@@ -411,7 +382,7 @@ SyncLogic::processSyncData (const Name &name, DigestConstPtr digest, const char
vector<MissingDataInfo> v;
BOOST_FOREACH (LeafConstPtr leaf, diff.getLeaves().get<ordered>())
{
DiffLeafConstPtr diffLeaf = dynamic_pointer_cast<const DiffLeaf> (leaf);
DiffLeafConstPtr diffLeaf = boost::dynamic_pointer_cast<const DiffLeaf> (leaf);
BOOST_ASSERT (diffLeaf != 0);
NameInfoConstPtr info = diffLeaf->getInfo();
@@ -424,7 +395,7 @@ SyncLogic::processSyncData (const Name &name, DigestConstPtr digest, const char
SeqNo oldSeq;
{
boost::recursive_mutex::scoped_lock lock (m_stateMutex);
tie (inserted, updated, oldSeq) = m_state->update (info, seq);
boost::tie (inserted, updated, oldSeq) = m_state->update (info, seq);
}
if (inserted || updated)
@@ -499,10 +470,9 @@ SyncLogic::processSyncData (const Name &name, DigestConstPtr digest, const char
// satisfyPendingSyncInterests (diffLog); // if there are interests in PIT, there is a point to satisfy them using new state
// if state has changed, then it is safe to express a new interest
m_scheduler.cancel (REEXPRESSING_INTEREST);
m_scheduler.schedule (TIME_SECONDS_WITH_JITTER (0),
func_lib::bind (&SyncLogic::sendSyncInterest, this),
REEXPRESSING_INTEREST);
m_scheduler.cancelEvent (m_reexpressingInterestId);
m_reexpressingInterestId = m_scheduler.scheduleEvent (time::milliseconds(GET_RANDOM (m_reexpressionJitter)),
bind (&SyncLogic::sendSyncInterest, this));
}
}
@@ -580,7 +550,7 @@ SyncLogic::insertToDiffLog (DiffStatePtr diffLog)
}
void
SyncLogic::addLocalNames (const Name &prefix, uint32_t session, uint32_t seq)
SyncLogic::addLocalNames (const Name &prefix, uint64_t session, uint64_t seq)
{
DiffStatePtr diff;
{
@@ -651,19 +621,19 @@ SyncLogic::sendSyncInterest ()
_LOG_DEBUG("sendSyncInterest: " << m_outstandingInterestName);
m_scheduler.cancel (REEXPRESSING_INTEREST);
m_scheduler.schedule (TIME_SECONDS_WITH_JITTER (m_syncInterestReexpress),
func_lib::bind (&SyncLogic::sendSyncInterest, this),
REEXPRESSING_INTEREST);
m_scheduler.cancelEvent (m_reexpressingInterestId);
m_reexpressingInterestId = m_scheduler.scheduleEvent (time::seconds(m_syncInterestReexpress)+time::milliseconds(GET_RANDOM (m_reexpressionJitter)),
bind (&SyncLogic::sendSyncInterest, this));
ndn::Interest interest(m_outstandingInterestName);
interest.setMustBeFresh(true);
OnVerified onVerified = func_lib::bind(&SyncLogic::onSyncDataVerified, this, _1);
OnVerifyFailed onVerifyFailed = func_lib::bind(&SyncLogic::onSyncDataVerifyFailed, this, _1);
OnDataValidated onValidated = bind(&SyncLogic::onSyncDataValidated, this, _1);
OnDataValidationFailed onValidationFailed = bind(&SyncLogic::onSyncDataValidationFailed, this, _1);
m_face->expressInterest(interest,
func_lib::bind(&SyncLogic::onSyncData, this, _1, _2, onVerified, onVerifyFailed),
func_lib::bind(&SyncLogic::onSyncDataTimeout, this, _1, 0, onVerified, onVerifyFailed));
bind(&SyncLogic::onSyncData, this, _1, _2, onValidated, onValidationFailed),
bind(&SyncLogic::onSyncTimeout, this, _1));
}
void
@@ -675,25 +645,24 @@ SyncLogic::sendSyncRecoveryInterests (DigestConstPtr digest)
Name interestName = m_syncPrefix;
interestName.append("recovery").append(os.str());
TimeDuration nextRetransmission = TIME_MILLISECONDS_WITH_JITTER (m_recoveryRetransmissionInterval);
time::Duration nextRetransmission = time::milliseconds (m_recoveryRetransmissionInterval + GET_RANDOM (m_reexpressionJitter));
m_recoveryRetransmissionInterval <<= 1;
m_scheduler.cancel (REEXPRESSING_RECOVERY_INTEREST);
m_scheduler.cancelEvent (m_reexpressingRecoveryInterestId);
if (m_recoveryRetransmissionInterval < 100*1000) // <100 seconds
{
m_scheduler.schedule (nextRetransmission,
func_lib::bind (&SyncLogic::sendSyncRecoveryInterests, this, digest),
REEXPRESSING_RECOVERY_INTEREST);
}
m_reexpressingRecoveryInterestId = m_scheduler.scheduleEvent (nextRetransmission,
bind (&SyncLogic::sendSyncRecoveryInterests, this, digest));
ndn::Interest interest(interestName);
interest.setMustBeFresh(true);
OnVerified onVerified = func_lib::bind(&SyncLogic::onSyncDataVerified, this, _1);
OnVerifyFailed onVerifyFailed = func_lib::bind(&SyncLogic::onSyncDataVerifyFailed, this, _1);
OnDataValidated onValidated = bind(&SyncLogic::onSyncDataValidated, this, _1);
OnDataValidationFailed onValidationFailed = bind(&SyncLogic::onSyncDataValidationFailed, this, _1);
m_face->expressInterest(interest,
func_lib::bind(&SyncLogic::onSyncData, this, _1, _2, onVerified, onVerifyFailed),
func_lib::bind(&SyncLogic::onSyncDataTimeout, this, _1, 0, onVerified, onVerifyFailed));
bind(&SyncLogic::onSyncData, this, _1, _2, onValidated, onValidationFailed),
bind(&SyncLogic::onSyncTimeout, this, _1));
}
@@ -713,12 +682,12 @@ SyncLogic::sendSyncData (const Name &name, DigestConstPtr digest, SyncStateMsg &
_LOG_TRACE (">> D " << name);
int size = ssm.ByteSize();
char *wireData = new char[size];
Name signingIdentity = m_policy->inferSigningIdentity(name);
ssm.SerializeToArray(wireData, size);
Data syncData(name);
syncData.setContent(reinterpret_cast<const uint8_t*>(wireData), size);
m_keyChain->signByIdentity(syncData, signingIdentity);
m_keyChain->sign(syncData);
m_face->put(syncData);
@@ -735,10 +704,9 @@ SyncLogic::sendSyncData (const Name &name, DigestConstPtr digest, SyncStateMsg &
{
_LOG_TRACE ("Satisfied our own Interest. Re-expressing (hopefully with a new digest)");
m_scheduler.cancel (REEXPRESSING_INTEREST);
m_scheduler.schedule (TIME_SECONDS_WITH_JITTER (0),
bind (&SyncLogic::sendSyncInterest, this),
REEXPRESSING_INTEREST);
m_scheduler.cancelEvent (m_reexpressingInterestId);
m_reexpressingInterestId = m_scheduler.scheduleEvent (time::milliseconds(GET_RANDOM (m_reexpressionJitter)),
bind (&SyncLogic::sendSyncInterest, this));
}
}
+27 -47
View File
@@ -31,15 +31,14 @@
#include <map>
#include <ndn-cpp-dev/face.hpp>
#include <ndn-cpp-dev/security/verifier.hpp>
#include <ndn-cpp-dev/security/validator.hpp>
#include <ndn-cpp-dev/security/key-chain.hpp>
#include <ndn-cpp-dev/util/scheduler.hpp>
#include "sync-interest-table.h"
#include "sync-diff-state.h"
#include "sync-full-state.h"
#include "sync-std-name-info.h"
#include "sync-scheduler.h"
#include "sec-policy-sync.h"
#include "sync-diff-state-container.h"
@@ -88,14 +87,14 @@ public:
* the app data when new remote names are learned
*/
SyncLogic (const ndn::Name& syncPrefix,
ndn::ptr_lib::shared_ptr<SecPolicySync> syncPolicyManager,
ndn::ptr_lib::shared_ptr<ndn::Face> face,
ndn::shared_ptr<ndn::Validator> validator,
ndn::shared_ptr<ndn::Face> face,
LogicUpdateCallback onUpdate,
LogicRemoveCallback onRemove);
SyncLogic (const ndn::Name& syncPrefix,
ndn::ptr_lib::shared_ptr<SecPolicySync> syncPolicyManager,
ndn::ptr_lib::shared_ptr<ndn::Face> face,
ndn::shared_ptr<ndn::Validator> validator,
ndn::shared_ptr<ndn::Face> face,
LogicPerBranchCallback onUpdateBranch);
~SyncLogic ();
@@ -103,20 +102,20 @@ public:
/**
* a wrapper for the same func in SyncApp
*/
void addLocalNames (const ndn::Name &prefix, uint32_t session, uint32_t seq);
void addLocalNames (const ndn::Name &prefix, uint64_t session, uint64_t seq);
/**
* @brief respond to the Sync Interest; a lot of logic needs to go in here
* @param interest the Sync Interest in string format
*/
void respondSyncInterest (ndn::ptr_lib::shared_ptr<ndn::Interest> interest);
void respondSyncInterest (ndn::shared_ptr<ndn::Interest> interest);
/**
* @brief process the fetched sync data
* @param name the data name
* @param dataBuffer the sync data
*/
void respondSyncData (ndn::ptr_lib::shared_ptr<ndn::Data> data);
void respondSyncData (ndn::shared_ptr<ndn::Data> data);
/**
* @brief remove a participant's subtree from the sync tree
@@ -128,7 +127,7 @@ public:
getRootDigest();
#ifdef _DEBUG
Scheduler &
ndn::Scheduler &
getScheduler () { return m_scheduler; }
#endif
@@ -146,46 +145,31 @@ public:
std::map<std::string, bool>
getBranchPrefixes() const;
private:
// void
// connectToDaemon();
// void
// onConnectionData(const ndn::ptr_lib::shared_ptr<const ndn::Interest>& interest,
// const ndn::ptr_lib::shared_ptr<ndn::Data>& data);
// void
// onConnectionDataTimeout(const ndn::ptr_lib::shared_ptr<const ndn::Interest>& interest);
private:
void
delayedChecksLoop ();
void
onSyncInterest (const ndn::ptr_lib::shared_ptr<const ndn::Name>& prefix,
const ndn::ptr_lib::shared_ptr<const ndn::Interest>& interest,
ndn::Transport& transport,
uint64_t registeredPrefixId);
onSyncInterest (const ndn::shared_ptr<const ndn::Name>& prefix,
const ndn::shared_ptr<const ndn::Interest>& interest);
void
onSyncRegisterFailed(const ndn::ptr_lib::shared_ptr<const ndn::Name>& prefix);
onSyncRegisterFailed(const ndn::shared_ptr<const ndn::Name>& prefix);
void
onSyncData(const ndn::ptr_lib::shared_ptr<const ndn::Interest>& interest,
const ndn::ptr_lib::shared_ptr<ndn::Data>& data,
const ndn::OnVerified& onVerified,
const ndn::OnVerifyFailed& onVerifyFailed);
onSyncData(const ndn::shared_ptr<const ndn::Interest>& interest,
const ndn::shared_ptr<ndn::Data>& data,
const ndn::OnDataValidated& onValidated,
const ndn::OnDataValidationFailed& onValidationFailed);
void
onSyncDataTimeout(const ndn::ptr_lib::shared_ptr<const ndn::Interest>& interest,
int retry,
const ndn::OnVerified& onVerified,
const ndn::OnVerifyFailed& onVerifyFailed);
onSyncTimeout(const ndn::shared_ptr<const ndn::Interest>& interest);
void
onSyncDataVerifyFailed(const ndn::ptr_lib::shared_ptr<ndn::Data>& data);
onSyncDataValidationFailed(const ndn::shared_ptr<const ndn::Data>& data);
void
onSyncDataVerified(const ndn::ptr_lib::shared_ptr<ndn::Data>& data);
onSyncDataValidated(const ndn::shared_ptr<const ndn::Data>& data);
void
processSyncInterest (const ndn::Name &name,
@@ -238,13 +222,12 @@ private:
LogicRemoveCallback m_onRemove;
LogicPerBranchCallback m_onUpdateBranch;
bool m_perBranch;
ndn::ptr_lib::shared_ptr<SecPolicySync> m_policy;
ndn::ptr_lib::shared_ptr<ndn::Verifier> m_verifier;
ndn::ptr_lib::shared_ptr<ndn::Validator> m_validator;
ndn::ptr_lib::shared_ptr<ndn::KeyChain> m_keyChain;
ndn::ptr_lib::shared_ptr<ndn::Face> m_face;
uint64_t m_syncRegisteredPrefixId;
const ndn::RegisteredPrefixId* m_syncRegisteredPrefixId;
Scheduler m_scheduler;
ndn::Scheduler m_scheduler;
#ifndef NS3_MODULE
boost::mt19937 m_randomGenerator;
@@ -268,12 +251,9 @@ private:
static const int m_defaultRecoveryRetransmitInterval = 200; // milliseconds
uint32_t m_recoveryRetransmissionInterval; // milliseconds
enum EventLabels
{
DELAYED_INTEREST_PROCESSING = 1,
REEXPRESSING_INTEREST = 2,
REEXPRESSING_RECOVERY_INTEREST = 3
};
ndn::EventId m_delayedInterestProcessingId;
ndn::EventId m_reexpressingInterestId;
ndn::EventId m_reexpressingRecoveryInterestId;
};
+8 -7
View File
@@ -18,6 +18,7 @@
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
* Chaoyi Bian <bcy@pku.edu.cn>
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
* Yingdi Yu <yingdi@cs.ucla.edu>
*/
#ifndef SYNC_SEQ_NO_H
@@ -72,7 +73,7 @@ public:
* @brief Constructor with just sequence number. Session assumed to be zero
* @param seq Sequence number
*/
SeqNo (uint32_t seq)
SeqNo (uint64_t seq)
: m_valid (true)
, m_session (0)
, m_seq (seq)
@@ -83,7 +84,7 @@ public:
* @param session Session ID
* @param seq Sequence number
*/
SeqNo (uint32_t session, uint32_t seq)
SeqNo (uint64_t session, uint64_t seq)
: m_valid (true)
, m_session (session)
, m_seq (seq)
@@ -148,20 +149,20 @@ public:
/**
* @brief Get session id
*/
uint32_t getSession () const
uint64_t getSession () const
{ return m_session; }
/**
* @brief Get sequence number
*/
uint32_t getSeq () const
uint64_t getSeq () const
{ return m_seq; }
/**
* @brief Set sequence number
*/
void
setSeq(uint32_t seq)
setSeq(uint64_t seq)
{ m_seq = seq; }
private:
@@ -173,7 +174,7 @@ private:
* Note that session IDs for the same name should always increase. So, the good choice
* for the session ID is client's timestamp
*/
uint32_t m_session;
uint64_t m_session;
/**
* @brief Sequence number
@@ -182,7 +183,7 @@ private:
*
* For now, wrapping sequence number after max to zero is not supported
*/
uint32_t m_seq;
uint64_t m_seq;
};
inline std::ostream &
+28 -42
View File
@@ -23,53 +23,44 @@
using namespace std;
using namespace ndn;
using namespace ndn::ptr_lib;
INIT_LOGGER ("SyncSocket");
namespace Sync {
SyncSocket::SyncSocket (const string &syncPrefix,
shared_ptr<SecPolicySync> policy,
SyncSocket::SyncSocket (const Name &syncPrefix,
shared_ptr<Validator> validator,
shared_ptr<Face> face,
NewDataCallback dataCallback,
RemoveCallback rmCallback )
: m_newDataCallback(dataCallback)
, m_policy(policy)
, m_verifier(new Verifier(policy))
, m_validator(validator)
, m_keyChain(new KeyChain())
, m_face(face)
, m_syncLogic (syncPrefix,
policy,
validator,
face,
bind(&SyncSocket::passCallback, this, _1),
rmCallback)
{
m_verifier->setFace(face);
}
{}
SyncSocket::~SyncSocket()
{
}
bool
SyncSocket::publishData(const Name &prefix, uint32_t session, const char *buf, size_t len, int freshness)
SyncSocket::publishData(const Name &prefix, uint64_t session, const char *buf, size_t len, int freshness)
{
uint32_t sequence = getNextSeq(prefix, session);
ostringstream sessionStream;
ostringstream seqStream;
sessionStream << session;
seqStream << sequence;
uint64_t sequence = getNextSeq(prefix, session);
Name dataName = prefix;
dataName.append(sessionStream.str()).append(seqStream.str());
Name signingIdentity = m_policy->inferSigningIdentity(dataName);
dataName.append(boost::lexical_cast<string>(session)).append(boost::lexical_cast<string>(sequence));
Data data(dataName);
data.setContent(reinterpret_cast<const uint8_t*>(buf), len);
data.setFreshnessPeriod(freshness);
m_keyChain->signByIdentity(data, signingIdentity);
m_keyChain->sign(data);
m_face->put(data);
@@ -80,40 +71,35 @@ SyncSocket::publishData(const Name &prefix, uint32_t session, const char *buf, s
}
void
SyncSocket::fetchData(const Name &prefix, const SeqNo &seq, const OnVerified& onVerified, int retry)
SyncSocket::fetchData(const Name &prefix, const SeqNo &seq, const OnDataValidated& onValidated, int retry)
{
ostringstream sessionStream;
ostringstream seqStream;
sessionStream << seq.getSession();
seqStream << seq.getSeq();
Name interestName = prefix;
interestName.append(sessionStream.str()).append(seqStream.str());
interestName.append(boost::lexical_cast<string>(seq.getSession())).append(boost::lexical_cast<string>(seq.getSeq()));
const OnVerifyFailed& onVerifyFailed = bind(&SyncSocket::onDataVerifyFailed, this, _1);
const OnDataValidationFailed& onValidationFailed = bind(&SyncSocket::onDataValidationFailed, this, _1);
ndn::Interest interest(interestName);
interest.setMustBeFresh(true);
m_face->expressInterest(interest,
bind(&SyncSocket::onData, this, _1, _2, onVerified, onVerifyFailed),
bind(&SyncSocket::onDataTimeout, this, _1, retry, onVerified, onVerifyFailed));
bind(&SyncSocket::onData, this, _1, _2, onValidated, onValidationFailed),
bind(&SyncSocket::onDataTimeout, this, _1, retry, onValidated, onValidationFailed));
}
void
SyncSocket::onData(const shared_ptr<const ndn::Interest>& interest,
const shared_ptr<Data>& data,
const OnVerified& onVerified,
const OnVerifyFailed& onVerifyFailed)
const OnDataValidated& onValidated,
const OnDataValidationFailed& onValidationFailed)
{
m_verifier->verifyData(data, onVerified, onVerifyFailed);
m_validator->validate(data, onValidated, onValidationFailed);
}
void
SyncSocket::onDataTimeout(const shared_ptr<const ndn::Interest>& interest,
int retry,
const OnVerified& onVerified,
const OnVerifyFailed& onVerifyFailed)
const OnDataValidated& onValidated,
const OnDataValidationFailed& onValidationFailed)
{
if(retry > 0)
{
@@ -122,14 +108,14 @@ SyncSocket::onDataTimeout(const shared_ptr<const ndn::Interest>& interest,
this,
_1,
_2,
onVerified,
onVerifyFailed),
onValidated,
onValidationFailed),
bind(&SyncSocket::onDataTimeout,
this,
_1,
retry - 1,
onVerified,
onVerifyFailed));
onValidated,
onValidationFailed));
}
else
@@ -137,14 +123,14 @@ SyncSocket::onDataTimeout(const shared_ptr<const ndn::Interest>& interest,
}
void
SyncSocket::onDataVerifyFailed(const shared_ptr<Data>& data)
SyncSocket::onDataValidationFailed(const shared_ptr<const Data>& data)
{
_LOG_DEBUG("data cannot be verified!");
}
uint32_t
SyncSocket::getNextSeq (const Name &prefix, uint32_t session)
uint64_t
SyncSocket::getNextSeq (const Name &prefix, uint64_t session)
{
SequenceLog::iterator i = m_sequenceLog.find (prefix);
+25 -24
View File
@@ -22,11 +22,12 @@
#define SYNC_SOCKET_H
#include "sync-logic.h"
#include <boost/function.hpp>
#include "sync-seq-no.h"
#include <ndn-cpp-dev/face.hpp>
#include <ndn-cpp-dev/security/verifier.hpp>
#include <ndn-cpp-dev/security/validator.hpp>
#include <ndn-cpp-dev/security/key-chain.hpp>
#include <utility>
#include <map>
#include <vector>
@@ -41,8 +42,9 @@ namespace Sync {
class SyncSocket
{
public:
typedef boost::function< void (const std::vector<MissingDataInfo> &, SyncSocket * ) > NewDataCallback;
typedef boost::function< void ( const std::string &/*prefix*/ ) > RemoveCallback;
typedef ndn::function< void (const std::vector<MissingDataInfo> &, SyncSocket * ) > NewDataCallback;
typedef ndn::function< void (const std::string &/*prefix*/ ) > RemoveCallback;
/**
* @brief the constructor for SyncAppSocket; the parameter syncPrefix
* should be passed to the constructor of m_syncAppWrapper; the other
@@ -54,30 +56,30 @@ public:
* @param syncPrefix the name prefix for Sync Interest
* @param dataCallback the callback to process data
*/
SyncSocket (const std::string &syncPrefix,
ndn::ptr_lib::shared_ptr<SecPolicySync> policy,
ndn::ptr_lib::shared_ptr<ndn::Face> face,
SyncSocket (const ndn::Name &syncPrefix,
ndn::shared_ptr<ndn::Validator> validator,
ndn::shared_ptr<ndn::Face> face,
NewDataCallback dataCallback,
RemoveCallback rmCallback);
~SyncSocket ();
bool
publishData(const ndn::Name &prefix, uint32_t session, const char *buf, size_t len, int freshness);
publishData(const ndn::Name &prefix, uint64_t session, const char *buf, size_t len, int freshness);
void
remove (const ndn::Name &prefix)
{ m_syncLogic.remove(prefix); }
void
fetchData(const ndn::Name &prefix, const SeqNo &seq, const ndn::OnVerified& onVerified, int retry = 0);
fetchData(const ndn::Name &prefix, const SeqNo &seq, const ndn::OnDataValidated& onValidated, int retry = 0);
std::string
getRootDigest()
{ return m_syncLogic.getRootDigest(); }
uint32_t
getNextSeq (const ndn::Name &prefix, uint32_t session);
uint64_t
getNextSeq (const ndn::Name &prefix, uint64_t session);
SyncLogic &
getLogic ()
@@ -94,28 +96,27 @@ private:
{ m_newDataCallback(v, this); }
void
onData(const ndn::ptr_lib::shared_ptr<const ndn::Interest>& interest,
const ndn::ptr_lib::shared_ptr<ndn::Data>& data,
const ndn::OnVerified& onVerified,
const ndn::OnVerifyFailed& onVerifyFailed);
onData(const ndn::shared_ptr<const ndn::Interest>& interest,
const ndn::shared_ptr<ndn::Data>& data,
const ndn::OnDataValidated& onValidated,
const ndn::OnDataValidationFailed& onValidationFailed);
void
onDataTimeout(const ndn::ptr_lib::shared_ptr<const ndn::Interest>& interest,
int retry,
const ndn::OnVerified& onVerified,
const ndn::OnVerifyFailed& onVerifyFailed);
onDataTimeout(const ndn::shared_ptr<const ndn::Interest>& interest,
int retry,
const ndn::OnDataValidated& onValidated,
const ndn::OnDataValidationFailed& onValidationFailed);
void
onDataVerifyFailed(const ndn::ptr_lib::shared_ptr<ndn::Data>& data);
onDataValidationFailed(const ndn::shared_ptr<const ndn::Data>& data);
private:
typedef std::map<ndn::Name, SeqNo> SequenceLog;
NewDataCallback m_newDataCallback;
SequenceLog m_sequenceLog;
ndn::ptr_lib::shared_ptr<SecPolicySync> m_policy;
ndn::ptr_lib::shared_ptr<ndn::Verifier> m_verifier;
ndn::ptr_lib::shared_ptr<ndn::KeyChain> m_keyChain;
ndn::ptr_lib::shared_ptr<ndn::Face> m_face;
ndn::shared_ptr<ndn::Validator> m_validator;
ndn::shared_ptr<ndn::KeyChain> m_keyChain;
ndn::shared_ptr<ndn::Face> m_face;
SyncLogic m_syncLogic;
};
+2 -2
View File
@@ -156,8 +156,8 @@ operator >> (SyncStateMsg &issm, State &state)
NameInfoConstPtr info = StdNameInfo::FindOrCreate (ss.name());
if (ss.type() == SyncState::UPDATE)
{
uint32_t session = lexical_cast<uint32_t>(ss.seqno().session());
uint32_t seq = lexical_cast<uint32_t>(ss.seqno().seq());
uint64_t session = lexical_cast<uint64_t>(ss.seqno().session());
uint64_t seq = lexical_cast<uint64_t>(ss.seqno().seq());
SeqNo seqNo(session, seq);
state.update(info, seqNo);
}
+2 -2
View File
@@ -12,8 +12,8 @@ message SyncState
required ActionType type = 2;
message SeqNo
{
required uint32 seq = 1;
required uint32 session = 2;
required uint64 seq = 1;
required uint64 session = 2;
}
optional SeqNo seqno = 3;
}
+13
View File
@@ -0,0 +1,13 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2013, Regents of the University of California
*
* BSD license, See the LICENSE file for more information
*
* Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
#define BOOST_TEST_MAIN 1
#define BOOST_TEST_DYN_LINK 1
#include <boost/test/unit_test.hpp>
-2
View File
@@ -109,5 +109,3 @@ BOOST_AUTO_TEST_CASE (AppDataPublishAndFetchTest)
}
*/
-1
View File
@@ -20,7 +20,6 @@
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
#define BOOST_TEST_MAIN 1
#include <boost/test/unit_test.hpp>
#include <boost/test/output_test_stream.hpp>
using boost::test_tools::output_test_stream;
+250 -121
View File
@@ -29,6 +29,7 @@ using boost::test_tools::output_test_stream;
#include "sync-logging.h"
#include "sync-socket.h"
#include <ndn-cpp-dev/security/validator-null.hpp>
extern "C" {
#include <unistd.h>
@@ -45,24 +46,24 @@ INIT_LOGGER ("Test.AppSocket");
class TestSocketApp {
public:
map<string, string> data;
void set(ndn::Ptr<ndn::Data> dataPacket) {
map<ndn::Name, string> data;
void set(const ndn::shared_ptr<const ndn::Data>& dataPacket) {
// _LOG_FUNCTION (this << ", " << str1);
string str1(dataPacket->getName().toUri());
string str2(dataPacket->content().buf(), dataPacket->content().size());
data.insert(make_pair(str1, str2));
ndn::Name dataName(dataPacket->getName());
string str2(reinterpret_cast<const char*>(dataPacket->getContent().value()), dataPacket->getContent().value_size());
data.insert(make_pair(dataName, str2));
// cout << str1 << ", " << str2 << endl;
}
void set(string str1, const char * buf, int len) {
void set(ndn::Name name, const char * buf, int len) {
string str2(buf, len);
data.insert(make_pair(str1, str2));
data.insert(make_pair(name, str2));
}
void setNum(ndn::Ptr<ndn::Data> dataPacket) {
int n = dataPacket->content().size() / 4;
void setNum(const ndn::shared_ptr<const ndn::Data>& dataPacket) {
int n = dataPacket->getContent().value_size() / 4;
int *numbers = new int [n];
memcpy(numbers, dataPacket->content().buf(), dataPacket->content().size());
memcpy(numbers, dataPacket->getContent().value(), dataPacket->getContent().value_size());
for (int i = 0; i < n; i++) {
sum += numbers[i];
}
@@ -70,7 +71,7 @@ public:
}
void setNum(string str1, const char * buf, int len) {
void setNum(ndn::Name name, const char * buf, int len) {
int n = len / 4;
int *numbers = new int [n];
memcpy(numbers, buf, len);
@@ -114,11 +115,11 @@ public:
}
string toString(){
map<string, string>::iterator it = data.begin();
map<ndn::Name, string>::iterator it = data.begin();
string str = "\n";
for (; it != data.end(); ++it){
str += "<";
str += it->first;
str += it->first.toUri();
str += "|";
str += it->second;
str += ">";
@@ -130,118 +131,246 @@ public:
};
BOOST_AUTO_TEST_CASE (AppSocketTest)
class TestSet1{
public:
TestSet1(ndn::shared_ptr<boost::asio::io_service> ioService)
: m_syncPrefix("/let/us/sync")
, m_validator(new ndn::ValidatorNull())
, m_face1(new ndn::Face(ioService))
, m_face2(new ndn::Face(ioService))
, m_face3(new ndn::Face(ioService))
, m_p1("/irl.cs.ucla.edu")
, m_p2("/yakshi.org")
, m_p3("/google.com")
{}
void
createSyncSocket1()
{
_LOG_DEBUG ("s1");
m_s1 = make_shared<SyncSocket>(m_syncPrefix, m_validator, m_face1,
bind(&TestSocketApp::fetchAll, &m_a1, _1, _2),
bind(&TestSocketApp::pass, &m_a1, _1));
}
void
createSyncSocket2()
{
_LOG_DEBUG ("s2");
m_s2 = make_shared<SyncSocket>(m_syncPrefix, m_validator, m_face2,
bind(&TestSocketApp::fetchAll, &m_a2, _1, _2),
bind(&TestSocketApp::pass, &m_a2, _1));
}
void
createSyncSocket3()
{
_LOG_DEBUG ("s3");
m_s3 = make_shared<SyncSocket>(m_syncPrefix, m_validator, m_face3,
bind(&TestSocketApp::fetchAll, &m_a3, _1, _2),
bind(&TestSocketApp::pass, &m_a3, _1));
}
void
publishSocket1(uint32_t session, string data)
{
_LOG_DEBUG ("s1 publish");
m_s1->publishData (m_p1, session, data.c_str(), data.size(), 1000);
}
void
publishSocket2(uint32_t session, string data)
{
_LOG_DEBUG ("s2 publish");
m_s2->publishData (m_p2, session, data.c_str(), data.size(), 1000);
}
void
publishSocket3(uint32_t session, string data)
{
_LOG_DEBUG ("s3 publish");
m_s3->publishData (m_p3, session, data.c_str(), data.size(), 1000);
}
void
setSocket1(string suffix, string data)
{
_LOG_DEBUG ("a1 set");
ndn::Name name = m_p1;
name.append(suffix);
m_a1.set (name, data.c_str(), data.size());
}
void
setSocket2(string suffix, string data)
{
_LOG_DEBUG ("a2 set");
ndn::Name name = m_p2;
name.append(suffix);
m_a2.set (name, data.c_str(), data.size());
}
void
setSocket3(string suffix, string data)
{
_LOG_DEBUG ("a3 set");
ndn::Name name = m_p3;
name.append(suffix);
m_a3.set (name, data.c_str(), data.size());
}
void
check()
{
BOOST_CHECK_EQUAL(m_a1.toString(), m_a2.toString());
BOOST_CHECK_EQUAL(m_a2.toString(), m_a3.toString());
}
TestSocketApp m_a1, m_a2, m_a3;
ndn::shared_ptr<ndn::ValidatorNull> m_validator;
ndn::shared_ptr<ndn::Face> m_face1, m_face2, m_face3;
ndn::Name m_p1, m_p2, m_p3;
ndn::shared_ptr<SyncSocket> m_s1, m_s2, m_s3;
ndn::Name m_syncPrefix;
};
class TestSet2{
public:
TestSet2(ndn::shared_ptr<boost::asio::io_service> ioService)
: m_syncPrefix("/this/is/the/prefix")
, m_validator(new ndn::ValidatorNull())
, m_face1(new ndn::Face(ioService))
, m_face2(new ndn::Face(ioService))
, m_p1("/xiaonei.com")
, m_p2("/mitbbs.com")
{}
void
createSyncSocket1()
{
_LOG_DEBUG ("s1");
m_s1 = make_shared<SyncSocket>(m_syncPrefix, m_validator, m_face1,
bind(&TestSocketApp::fetchNumbers, &m_a1, _1, _2),
bind(&TestSocketApp::pass, &m_a1, _1));
}
void
createSyncSocket2()
{
_LOG_DEBUG ("s2");
m_s2 = make_shared<SyncSocket>(m_syncPrefix, m_validator, m_face2,
bind(&TestSocketApp::fetchNumbers, &m_a2, _1, _2),
bind(&TestSocketApp::pass, &m_a2, _1));
}
void
publishSocket1(uint32_t session, string data)
{
_LOG_DEBUG ("s1 publish");
m_s1->publishData (m_p1, session, data.c_str(), data.size(), 1000);
}
void
publishSocket2(uint32_t session, string data)
{
_LOG_DEBUG ("s2 publish");
m_s2->publishData (m_p2, session, data.c_str(), data.size(), 1000);
}
void
setSocket1(const char* ptr, size_t size)
{
_LOG_DEBUG ("a1 setNum");
m_a1.setNum (m_p1, ptr, size);
}
void
setSocket2(const char* ptr, size_t size)
{
_LOG_DEBUG ("a2 setNum");
m_a2.setNum (m_p2, ptr, size);
}
void
check(int num)
{
BOOST_CHECK(m_a1.sum == m_a2.sum && m_a1.sum == num);
}
TestSocketApp m_a1, m_a2;
ndn::shared_ptr<ndn::ValidatorNull> m_validator;
ndn::shared_ptr<ndn::Face> m_face1, m_face2;
ndn::Name m_p1, m_p2;
ndn::shared_ptr<SyncSocket> m_s1, m_s2;
ndn::Name m_syncPrefix;
};
BOOST_AUTO_TEST_CASE (AppSocketTest1)
{
INIT_LOGGERS ();
TestSocketApp a1, a2, a3;
string syncPrefix("/let/us/sync");
string p1("/irl.cs.ucla.edu"), p2("/yakshi.org"), p3("/google.com");
ndn::Ptr<SyncPolicyManager> policyManager1 = ndn::Ptr<SyncPolicyManager>(new SyncPolicyManager(ndn::Name("/ndn/ucla.edu/alice"), ndn::Name("/ndn/ucla.edu/alice/KEY/dsk-1382934202/ID-CERT/%FD%FF%FF%FF%FF%DEk%C0%0B"), ndn::Name(syncPrefix)));
ndn::shared_ptr<boost::asio::io_service> ioService = ndn::make_shared<boost::asio::io_service>();
ndn::Scheduler scheduler(*ioService);
TestSet1 testSet1(ioService);
_LOG_DEBUG ("s1");
SyncSocket s1 (syncPrefix, policyManager1, bind(&TestSocketApp::fetchAll, &a1, _1, _2), bind(&TestSocketApp::pass, &a1, _1));
this_thread::sleep (posix_time::milliseconds (50));
_LOG_DEBUG ("s2");
SyncSocket s2 (syncPrefix, policyManager1, bind(&TestSocketApp::fetchAll, &a2, _1, _2), bind(&TestSocketApp::pass, &a2, _1));
this_thread::sleep (posix_time::milliseconds (50));
SyncSocket s3 (syncPrefix, policyManager1, bind(&TestSocketApp::fetchAll, &a3, _1, _2), bind(&TestSocketApp::pass, &a3, _1));
this_thread::sleep (posix_time::milliseconds (50));
// single source
scheduler.scheduleEvent(ndn::time::seconds(0.00), ndn::bind(&TestSet1::createSyncSocket1, &testSet1));
scheduler.scheduleEvent(ndn::time::seconds(0.05), ndn::bind(&TestSet1::createSyncSocket2, &testSet1));
scheduler.scheduleEvent(ndn::time::seconds(0.10), ndn::bind(&TestSet1::createSyncSocket3, &testSet1));
string data0 = "Very funny Scotty, now beam down my clothes";
_LOG_DEBUG ("s1 publish");
s1.publishData (p1, 0, data0.c_str(), data0.size(), 10);
this_thread::sleep (posix_time::milliseconds (1000));
scheduler.scheduleEvent(ndn::time::seconds(0.15), ndn::bind(&TestSet1::publishSocket1, &testSet1, 0, data0));
scheduler.scheduleEvent(ndn::time::seconds(1.15), ndn::bind(&TestSet1::setSocket1, &testSet1, "/0/0", data0));
scheduler.scheduleEvent(ndn::time::seconds(1.16), ndn::bind(&TestSet1::check, &testSet1));
string data1 = "Yes, give me that ketchup";
string data2 = "Don't look conspicuous, it draws fire";
scheduler.scheduleEvent(ndn::time::seconds(1.17), ndn::bind(&TestSet1::publishSocket1, &testSet1, 0, data1));
scheduler.scheduleEvent(ndn::time::seconds(1.18), ndn::bind(&TestSet1::publishSocket1, &testSet1, 0, data2));
scheduler.scheduleEvent(ndn::time::seconds(2.15), ndn::bind(&TestSet1::setSocket1, &testSet1, "/0/1", data1));
scheduler.scheduleEvent(ndn::time::seconds(2.16), ndn::bind(&TestSet1::setSocket1, &testSet1, "/0/2", data2));
scheduler.scheduleEvent(ndn::time::seconds(2.17), ndn::bind(&TestSet1::check, &testSet1));
string data3 = "You surf the Internet, I surf the real world";
string data4 = "I got a fortune cookie once that said 'You like Chinese food'";
string data5 = "Real men wear pink. Why? Because their wives make them";
scheduler.scheduleEvent(ndn::time::seconds(2.18), ndn::bind(&TestSet1::publishSocket3, &testSet1, 0, data3));
scheduler.scheduleEvent(ndn::time::seconds(2.20), ndn::bind(&TestSet1::publishSocket2, &testSet1, 0, data4));
scheduler.scheduleEvent(ndn::time::seconds(2.21), ndn::bind(&TestSet1::publishSocket2, &testSet1, 0, data5));
scheduler.scheduleEvent(ndn::time::seconds(3.21), ndn::bind(&TestSet1::setSocket3, &testSet1, "/0/0", data3));
scheduler.scheduleEvent(ndn::time::seconds(3.22), ndn::bind(&TestSet1::setSocket2, &testSet1, "/0/0", data4));
scheduler.scheduleEvent(ndn::time::seconds(3.23), ndn::bind(&TestSet1::setSocket2, &testSet1, "/0/1", data5));
// not sure weither this is simultanous data generation from multiple sources
_LOG_DEBUG ("Simultaneous publishing");
string data6 = "Shakespeare says: 'Prose before hos.'";
string data7 = "Pick good people, talent never wears out";
scheduler.scheduleEvent(ndn::time::seconds(3.30), ndn::bind(&TestSet1::publishSocket1, &testSet1, 0, data6));
scheduler.scheduleEvent(ndn::time::seconds(3.30), ndn::bind(&TestSet1::publishSocket2, &testSet1, 0, data7));
scheduler.scheduleEvent(ndn::time::seconds(4.80), ndn::bind(&TestSet1::setSocket1, &testSet1, "/0/3", data6));
scheduler.scheduleEvent(ndn::time::seconds(4.80), ndn::bind(&TestSet1::setSocket2, &testSet1, "/0/2", data7));
scheduler.scheduleEvent(ndn::time::seconds(4.90), ndn::bind(&TestSet1::check, &testSet1));
// // from code logic, we won't be fetching our own data
// a1.set(p1 + "/0/0", data0.c_str(), data0.size());
// BOOST_CHECK_EQUAL(a1.toString(), a2.toString());
// BOOST_CHECK_EQUAL(a2.toString(), a3.toString());
// // single source, multiple data at once
// string data1 = "Yes, give me that ketchup";
// string data2 = "Don't look conspicuous, it draws fire";
// _LOG_DEBUG ("s1 publish");
// s1.publishData (p1, 0, data1.c_str(), data1.size(), 10);
// _LOG_DEBUG ("s1 publish");
// s1.publishData (p1, 0, data2.c_str(), data2.size(), 10);
// this_thread::sleep (posix_time::milliseconds (1000));
// // from code logic, we won't be fetching our own data
// a1.set(p1 + "/0/1", data1.c_str(), data1.size());
// a1.set(p1 + "/0/2", data2.c_str(), data2.size());
// BOOST_CHECK_EQUAL(a1.toString(), a2.toString());
// BOOST_CHECK_EQUAL(a2.toString(), a3.toString());
// // another single source
// string data3 = "You surf the Internet, I surf the real world";
// string data4 = "I got a fortune cookie once that said 'You like Chinese food'";
// string data5 = "Real men wear pink. Why? Because their wives make them";
// _LOG_DEBUG ("s3 publish");
// s3.publishData(p3, 0, data3.c_str(), data3.size(), 10);
// this_thread::sleep (posix_time::milliseconds (200));
// // another single source, multiple data at once
// s2.publishData(p2, 0, data4.c_str(), data4.size(), 10);
// s2.publishData(p2, 0, data5.c_str(), data5.size(), 10);
// this_thread::sleep (posix_time::milliseconds (1000));
// // from code logic, we won't be fetching our own data
// a3.set(p3 + "/0/0", data3.c_str(), data3.size());
// a2.set(p2 + "/0/0", data4.c_str(), data4.size());
// a2.set(p2 + "/0/1", data5.c_str(), data5.size());
// BOOST_CHECK_EQUAL(a1.toString(), a2.toString());
// BOOST_CHECK_EQUAL(a2.toString(), a3.toString());
// // not sure weither this is simultanous data generation from multiple sources
// _LOG_DEBUG ("Simultaneous publishing");
// string data6 = "Shakespeare says: 'Prose before hos.'";
// string data7 = "Pick good people, talent never wears out";
// s1.publishData(p1, 0, data6.c_str(), data6.size(), 10);
// // this_thread::sleep (posix_time::milliseconds (1000));
// s2.publishData(p2, 0, data7.c_str(), data7.size(), 10);
// this_thread::sleep (posix_time::milliseconds (1500));
// // from code logic, we won't be fetching our own data
// a1.set(p1 + "/0/3", data6.c_str(), data6.size());
// a2.set(p2 + "/0/2", data7.c_str(), data7.size());
// // a1.set(p1 + "/0/1", data6);
// // a2.set(p2 + "/0/0", data7);
// BOOST_CHECK_EQUAL(a1.toString(), a2.toString());
// BOOST_CHECK_EQUAL(a2.toString(), a3.toString());
// _LOG_DEBUG("Begin new test");
// std::cout << "Begin new Test " << std::endl;
// string syncRawPrefix = "/this/is/the/prefix";
// ndn::Ptr<SyncPolicyManager> policyManager2 = ndn::Ptr<SyncPolicyManager>(new SyncPolicyManager(ndn::Name("/ndn/ucla.edu/alice"), ndn::Name("/ndn/ucla.edu/alice/KEY/dsk-1382934202/ID-CERT/%FD%FF%FF%FF%FF%DEk%C0%0B"), ndn::Name(syncRawPrefix)));
// a1.sum = 0;
// a2.sum = 0;
// SyncSocket s4 (syncRawPrefix, policyManager2, bind(&TestSocketApp::fetchNumbers, &a1, _1, _2), bind(&TestSocketApp::pass, &a1, _1));
// SyncSocket s5 (syncRawPrefix, policyManager2, bind(&TestSocketApp::fetchNumbers, &a2, _1, _2), bind(&TestSocketApp::pass, &a2, _1));
// int num[5] = {0, 1, 2, 3, 4};
// string p4 = "/xiaonei.com";
// string p5 = "/mitbbs.com";
// s4.publishData(p4, 0,(const char *) num, sizeof(num), 10);
// a1.setNum(p4, (const char *) num, sizeof (num));
// this_thread::sleep (posix_time::milliseconds (1000));
// BOOST_CHECK(a1.sum == a2.sum && a1.sum == 10);
// int newNum[5] = {9, 7, 2, 1, 1};
// s5.publishData(p5, 0,(const char *) newNum, sizeof(newNum), 10);
// a2.setNum(p5, (const char *)newNum, sizeof (newNum));
// this_thread::sleep (posix_time::milliseconds (1000));
// BOOST_CHECK_EQUAL(a1.sum, a2.sum);
// BOOST_CHECK_EQUAL(a1.sum, 30);
// _LOG_DEBUG ("Finish");
ioService->run();
}
BOOST_AUTO_TEST_CASE (AppSocketTest2)
{
ndn::shared_ptr<boost::asio::io_service> ioService = ndn::make_shared<boost::asio::io_service>();
ndn::Scheduler scheduler(*ioService);
TestSet2 testSet2(ioService);
scheduler.scheduleEvent(ndn::time::seconds(0.00), ndn::bind(&TestSet2::createSyncSocket1, &testSet2));
scheduler.scheduleEvent(ndn::time::seconds(0.05), ndn::bind(&TestSet2::createSyncSocket2, &testSet2));
int num[5] = {0, 1, 2, 3, 4};
string data0((const char *) num, sizeof(num));
scheduler.scheduleEvent(ndn::time::seconds(0.10), ndn::bind(&TestSet2::publishSocket1, &testSet2, 0, data0));
scheduler.scheduleEvent(ndn::time::seconds(0.15), ndn::bind(&TestSet2::setSocket1, &testSet2, (const char *) num, sizeof (num)));
scheduler.scheduleEvent(ndn::time::seconds(1.00), ndn::bind(&TestSet2::check, &testSet2, 10));
int newNum[5] = {9, 7, 2, 1, 1};
string data1((const char *) newNum, sizeof(newNum));
scheduler.scheduleEvent(ndn::time::seconds(1.10), ndn::bind(&TestSet2::publishSocket2, &testSet2, 0, data1));
scheduler.scheduleEvent(ndn::time::seconds(1.15), ndn::bind(&TestSet2::setSocket2, &testSet2, (const char *) newNum, sizeof (newNum)));
scheduler.scheduleEvent(ndn::time::seconds(2.00), ndn::bind(&TestSet2::check, &testSet2, 30));
ioService->run();
}
+101 -32
View File
@@ -1,4 +1,4 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012 University of California, Los Angeles
*
@@ -27,8 +27,7 @@ using boost::test_tools::output_test_stream;
#include <boost/make_shared.hpp>
// #include <ndn.cxx/wrapper/wrapper.h>
#include "sync-policy-manager.h"
#include <ndn-cpp-dev/security/validator-null.hpp>
#include "sync-logic.h"
#include "sync-seq-no.h"
@@ -72,39 +71,109 @@ struct Handler
map<string, uint32_t> m_map;
};
class TestCore
{
public:
TestCore(ndn::shared_ptr<boost::asio::io_service> ioService)
: m_ioService(ioService)
{
m_l[0] = 0;
m_l[1] = 0;
m_validator = ndn::make_shared<ndn::ValidatorNull>();
}
~TestCore()
{
if(m_l[0] != 0)
delete m_l[0];
if(m_l[1] != 0)
delete m_l[1];
}
void
finish()
{
}
void
createSyncLogic(int index,
ndn::shared_ptr<Handler> h)
{
m_faces[index] = ndn::make_shared<ndn::Face>(m_ioService);
m_l[index] = new SyncLogic(ndn::Name("/bcast"),
m_validator, m_faces[index],
bind (&Handler::wrapper, &*h, _1),
bind (&Handler::onRemove, &*h, _1));
}
void
getOldDigestForOne()
{
m_oldDigest = m_l[0]->getRootDigest();
}
void
getNewDigestForOne()
{
m_newDigest = m_l[0]->getRootDigest();
}
void
addLocalNamesForOne(ndn::Name name, uint64_t session, uint64_t seq)
{
m_l[0]->addLocalNames(name, session, seq);
}
void
removeForOne(ndn::Name name)
{
m_l[0]->remove(name);
}
void
checkDigest()
{
BOOST_CHECK(m_oldDigest != m_newDigest);
}
public:
ndn::shared_ptr<boost::asio::io_service> m_ioService;
SyncLogic* m_l[2];
ndn::shared_ptr<ndn::Face> m_faces[2];
ndn::shared_ptr<ndn::ValidatorNull> m_validator;
string m_oldDigest;
string m_newDigest;
};
void
checkMapSize(ndn::shared_ptr<Handler> h, int size)
{ BOOST_CHECK_EQUAL (h->m_map.size (), size); }
BOOST_AUTO_TEST_CASE (SyncLogicTest)
{
// Handler h1 ("1");
ndn::shared_ptr<boost::asio::io_service> ioService = ndn::make_shared<boost::asio::io_service>();
ndn::Scheduler scheduler(*ioService);
TestCore testCore(ioService);
// ndn::Ptr<SyncPolicyManager> policyManager1 = ndn::Ptr<SyncPolicyManager>(new SyncPolicyManager(ndn::Name("/ndn/ucla.edu/alice"), ndn::Name("/ndn/ucla.edu/alice/KEY/dsk-1382934202/ID-CERT/%FD%FF%FF%FF%FF%DEk%C0%0B"), ndn::Name("/bcast")));
ndn::shared_ptr<Handler> h1 = ndn::make_shared<Handler>("1");
ndn::shared_ptr<Handler> h2 = ndn::make_shared<Handler>("2");
// SyncLogic l1 (ndn::Name("/bcast"),
// policyManager1,
// bind (&Handler::wrapper, &h1, _1), bind (&Handler::onRemove, &h1, _1));
// std::string oldDigest = l1.getRootDigest();
scheduler.scheduleEvent(ndn::time::seconds(0), ndn::bind(&TestCore::createSyncLogic, &testCore, 0, h1));
scheduler.scheduleEvent(ndn::time::seconds(0.1), ndn::bind(&TestCore::getOldDigestForOne, &testCore));
scheduler.scheduleEvent(ndn::time::seconds(0.2), ndn::bind(&TestCore::addLocalNamesForOne, &testCore, "/one", 1, 2));
scheduler.scheduleEvent(ndn::time::seconds(0.3), ndn::bind(&checkMapSize, h1, 0));
scheduler.scheduleEvent(ndn::time::seconds(0.4), ndn::bind(&TestCore::createSyncLogic, &testCore, 1, h2));
scheduler.scheduleEvent(ndn::time::seconds(0.5), ndn::bind(&checkMapSize, h1, 0));
scheduler.scheduleEvent(ndn::time::seconds(0.6), ndn::bind(&checkMapSize, h2, 1));
scheduler.scheduleEvent(ndn::time::seconds(0.7), ndn::bind(&TestCore::removeForOne, &testCore, "/one"));
scheduler.scheduleEvent(ndn::time::seconds(0.8), ndn::bind(&TestCore::getNewDigestForOne, &testCore));
scheduler.scheduleEvent(ndn::time::seconds(0.9), ndn::bind(&TestCore::checkDigest, &testCore));
scheduler.scheduleEvent(ndn::time::seconds(1.0), ndn::bind(&TestCore::finish, &testCore));
// l1.addLocalNames ("/one", 1, 2);
// BOOST_CHECK_EQUAL (h1.m_map.size (), 0);
// sleep (1);
// BOOST_CHECK_EQUAL (h1.m_map.size (), 0);
// Handler h2 ("2");
// ndn::Ptr<SyncPolicyManager> policyManager2 = ndn::Ptr<SyncPolicyManager>(new SyncPolicyManager(ndn::Name("/ndn/ucla.edu/bob"), ndn::Name("/ndn/ucla.edu/bob/KEY/dsk-1382934206/ID-CERT/%FD%FF%FF%FF%FF%DEl%0BC"), ndn::Name("/bcast")));
// SyncLogic l2 (ndn::Name("/bcast"),
// policyManager2,
// bind (&Handler::wrapper, &h2, _1), bind (&Handler::onRemove, &h2, _1));
// sleep (1);
// BOOST_CHECK_EQUAL (h1.m_map.size (), 0);
// BOOST_CHECK_EQUAL (h2.m_map.size (), 1);
// l1.remove ("/one");
// sleep(1);
// std::string newDigest = l1.getRootDigest();
// BOOST_CHECK(oldDigest != newDigest);
ioService->run();
}
-79
View File
@@ -1,79 +0,0 @@
#! /usr/bin/env python
# encoding: utf-8
'''
When using this tool, the wscript will look like:
def options(opt):
opt.tool_options('ndn_cpp', tooldir=["waf-tools"])
def configure(conf):
conf.load('compiler_cxx ndn_cpp')
def build(bld):
bld(source='main.cpp', target='app', use='NDNCPP')
Options are generated, in order to specify the location of ndn-cpp includes/libraries.
'''
import sys
import re
from waflib import Utils,Logs,Errors
from waflib.Configure import conf
NDNCPP_DIR=['/usr/local/ndn', '/usr', '/usr/local', '/opt/local','/sw']
NDNCPP_VERSION_FILE='ndn-cpp-config.h'
NDNCPP_VERSION_CODE='''
#include <iostream>
#include <ndn-cpp/ndn-cpp-config.h>
int main() { std::cout << NDN_CPP_PACKAGE_VERSION; }
'''
def options(opt):
opt.add_option('--ndn-cpp',type='string',default='/usr/local/ndn',dest='ndn_cpp_dir',help='''path to where ndn-cpp is installed, e.g. /usr/local/ndn''')
@conf
def __ndncpp_get_version_file(self,dir):
try:
return self.root.find_dir(dir).find_node('%s/%s' % ('include/ndn-cpp', NDNCPP_VERSION_FILE))
except:
return None
@conf
def ndncpp_get_version(self,dir):
val=self.check_cxx(fragment=NDNCPP_VERSION_CODE,includes=['%s/%s' % (dir, 'include')], execute=True, define_ret = True, mandatory=True)
return val
@conf
def ndncpp_get_root(self,*k,**kw):
root=k and k[0]or kw.get('path',None)
# Logs.pprint ('RED', ' %s' %root)
if root and self.__ndncpp_get_version_file(root):
return root
for dir in NDNCPP_DIR:
if self.__ndncpp_get_version_file(dir):
return dir
if root:
self.fatal('NDNCPP not found in %s'%root)
else:
self.fatal('NDNCPP not found, please provide a --ndn-cpp argument (see help)')
@conf
def check_ndncpp(self,*k,**kw):
if not self.env['CXX']:
self.fatal('load a c++ compiler first, conf.load("compiler_cxx")')
var=kw.get('uselib_store','NDNCPP')
self.start_msg('Checking ndn-cpp')
root = self.ndncpp_get_root(*k,**kw)
self.env.NDNCPP_VERSION=self.ndncpp_get_version(root)
self.env['INCLUDES_%s'%var]= '%s/%s' % (root, "include")
self.env['LIB_%s'%var] = "ndn-cpp"
self.env['LIBPATH_%s'%var] = '%s/%s' % (root, "lib")
self.end_msg(self.env.NDNCPP_VERSION)
if Logs.verbose:
Logs.pprint('CYAN',' NDNCPP include : %s'%self.env['INCLUDES_%s'%var])
Logs.pprint('CYAN',' NDNCPP lib : %s'%self.env['LIB_%s'%var])
Logs.pprint('CYAN',' NDNCPP libpath : %s'%self.env['LIBPATH_%s'%var])
-160
View File
@@ -1,160 +0,0 @@
#! /usr/bin/env python
# encoding: utf-8
'''
When using this tool, the wscript will look like:
def options(opt):
opt.tool_options('ndnx')
def configure(conf):
conf.load('compiler_c ndnx')
def build(bld):
bld(source='main.cpp', target='app', use='NDNX')
Options are generated, in order to specify the location of ndnx includes/libraries.
'''
import sys, re
from waflib import Utils, Logs, Errors, Options, ConfigSet
from waflib.Configure import conf
NDNX_DIR=['/usr','/usr/local','/opt/local','/sw']
NDNX_VERSION_FILE='ccn/ccn.h'
NDNX_VERSION_CODE='''
#include <ccn/ccn.h>
#include <stdio.h>
int main() { printf ("%d.%d.%d", ((CCN_API_VERSION/100000) % 100), ((CCN_API_VERSION/1000) % 100), (CCN_API_VERSION % 1000)); return 0; }
'''
@conf
def __ndnx_get_version_file(self,dir):
# Logs.pprint ('CYAN', ' + %s/%s/%s' % (dir, 'include', NDNX_VERSION_FILE))
try:
return self.root.find_dir(dir).find_node('%s/%s' % ('include', NDNX_VERSION_FILE))
except:
return None
@conf
def ndnx_get_version(self,dir):
val=self.check_cc(fragment=NDNX_VERSION_CODE,includes=['%s/%s' % (dir, 'include')],execute=True,define_ret = True, mandatory=True)
return val
@conf
def ndnx_get_root(self,*k,**kw):
root=Options.options.ndnx_dir or (k and k[0]) or kw.get('path',None)
if root:
if self.__ndnx_get_version_file(root):
return root
self.fatal('NDNx not found in %s'%root)
for dir in NDNX_DIR:
if self.__ndnx_get_version_file(dir):
return dir
self.fatal('NDNx not found, please provide a --ndnx argument (see help)')
@conf
def check_openssl(self,*k,**kw):
root = k and k[0] or kw.get('path',None) or Options.options.openssl
mandatory = kw.get('mandatory', True)
var = kw.get('var', 'SSL')
CODE = """
#include <openssl/crypto.h>
#include <stdio.h>
int main(int argc, char **argv) {
(void)argc;
printf ("%s", argv[0]);
return 0;
}
"""
if root:
testApp = self.check_cc (lib=['ssl', 'crypto'],
header_name='openssl/crypto.h',
define_name='HAVE_%s' % var,
uselib_store=var,
mandatory = mandatory,
cflags="-I%s/include" % root,
linkflags="-L%s/lib" % root,
execute = True, fragment = CODE, define_ret = True)
else:
testApp = libcrypto = self.check_cc (lib=['ssl', 'crypto'],
header_name='openssl/crypto.h',
define_name='HAVE_%s' % var,
uselib_store=var,
mandatory = mandatory,
execute = True, fragment = CODE, define_ret = True)
if not testApp:
return
self.start_msg ('Checking if selected openssl matches NDNx')
ndn_var = kw.get('ndn_var', "NDNX")
if Utils.unversioned_sys_platform () == "darwin":
def otool (binary):
p = Utils.subprocess.Popen (['/usr/bin/otool', '-L', binary],
stdout = Utils.subprocess.PIPE, )
for line in p.communicate()[0].split ('\n'):
if re.match ('.*/libcrypto\..*', line):
return line
selected_crypto = otool (testApp)
ccnd_crypto = otool ('%s/bin/ccnd' % self.env['%s_ROOT' % ndn_var])
if ccnd_crypto != selected_crypto:
self.fatal ("Selected openssl does not match used to compile NDNx (%s != %s)" %
(selected_crypto.strip (), ccnd_crypto.strip ()))
self.end_msg (True)
elif Utils.unversioned_sys_platform () == "linux" or Utils.unversioned_sys_platform () == "freebsd":
def ldd (binary):
p = Utils.subprocess.Popen (['/usr/bin/ldd', binary],
stdout = Utils.subprocess.PIPE, )
for line in p.communicate()[0].split ('\n'):
if re.match ('libcrypto\..*', line):
return line
selected_crypto = ldd (testApp)
ccnd_crypto = ldd ('%s/bin/ccnd' % self.env['%s_ROOT' % ndn_var])
if ccnd_crypto != selected_crypto:
self.fatal ("Selected openssl does not match used to compile NDNx (%s != %s)" %
(selected_crypto.strip (), ccnd_crypto.strip ()))
self.end_msg (True)
else:
self.end_msg ("Don't know how to check", 'YELLOW')
@conf
def check_ndnx(self,*k,**kw):
if not self.env['CC']:
self.fatal('load a c compiler first, conf.load("compiler_c")')
var=kw.get('uselib_store', 'NDNX')
self.start_msg('Checking for NDNx')
root = self.ndnx_get_root(*k,**kw);
self.env.NDNX_VERSION=self.ndnx_get_version(root)
self.env['INCLUDES_%s' % var]= '%s/%s' % (root, "include");
self.env['LIB_%s' % var] = "ccn"
self.env['LIBPATH_%s' % var] = '%s/%s' % (root, "lib")
self.env['%s_ROOT' % var] = root
self.end_msg("%s in %s " % (self.env.NDNX_VERSION, root))
if Logs.verbose:
Logs.pprint('CYAN',' NDNx include : %s'%self.env['INCLUDES_%s' % var])
Logs.pprint('CYAN',' NDNx lib : %s'%self.env['LIB_%s' % var])
Logs.pprint('CYAN',' NDNx libpath : %s'%self.env['LIBPATH_%s' % var])
def options(opt):
"""
NDNx options
"""
ndnopt = opt.add_option_group("NDNx Options")
ndnopt.add_option('--ndnx',type='string',default=None,dest='ndnx_dir',help='''path to where NDNx is installed, e.g. /usr/local''')
ndnopt.add_option('--openssl',type='string',default='',dest='openssl',help='''path to openssl, should be the same NDNx is compiled against''')
+3 -10
View File
@@ -15,11 +15,8 @@ def options(opt):
syncopt.add_option('--log4cxx', action='store_true',default=False,dest='log4cxx',help='''Compile with log4cxx''')
syncopt.add_option('--test', action='store_true',default=False,dest='_test',help='''build unit tests''')
opt.load('ndn_cpp', tooldir=['waf-tools'])
def configure(conf):
conf.load('compiler_c compiler_cxx gnu_dirs boost')
conf.load('ndn_cpp')
if conf.options.debug:
conf.define ('_DEBUG', 1)
@@ -34,15 +31,11 @@ def configure(conf):
else:
conf.add_supported_cxxflags (cxxflags = ['-O3', '-g'])
# conf.check_ndnx ()
conf.check_cfg(package='libndn-cpp-dev', args=['--cflags', '--libs'], uselib_store='NDNCPP', mandatory=True)
conf.check_cfg(package='libndn-cpp-et', args=['--cflags', '--libs'], uselib_store='NDN-CPP-ET', mandatory=True)
conf.check_cfg(package='openssl', args=['--cflags', '--libs'], uselib_store='OPENSSL', mandatory=True)
# conf.check_openssl ()
conf.check_boost(lib='system iostreams test thread')
conf.check_boost(lib='system iostreams thread unit_test_framework')
if conf.options.log4cxx:
conf.check_cfg(package='liblog4cxx', args=['--cflags', '--libs'], uselib_store='LOG4CXX', mandatory=True)
@@ -63,7 +56,7 @@ def build (bld):
# vnum = "1.0.0",
features=['cxx', 'cxxshlib'],
source = bld.path.ant_glob (['src/**/*.cc', 'src/**/*.proto']),
use = 'BOOST BOOST_IOSTREAMS BOOST_THREAD SSL NDNCPP NDN-CPP-ET OPENSSL',
use = 'BOOST NDNCPP OPENSSL',
includes = ['src'],
)
@@ -73,7 +66,7 @@ def build (bld):
target="unit-tests",
source = bld.path.ant_glob(['tests/**/*.cc']),
features=['cxx', 'cxxprogram'],
use = 'BOOST_TEST ChronoSync',
use = 'ChronoSync',
includes = ['src'],
)