Merge "Added Hint for Username format in Settings Window"
diff --git a/ccnx/ccnx-wrapper.cpp b/ccnx/ccnx-wrapper.cpp
index 5a6cfd3..a9f0821 100644
--- a/ccnx/ccnx-wrapper.cpp
+++ b/ccnx/ccnx-wrapper.cpp
@@ -43,11 +43,92 @@
namespace Ccnx {
+static int
+ccn_encode_Signature(struct ccn_charbuf *buf,
+ const char *digest_algorithm,
+ const void *witness,
+ size_t witness_size,
+ const struct ccn_signature *signature,
+ size_t signature_size)
+{
+ int res = 0;
+
+ if (signature == NULL)
+ return(-1);
+
+ res |= ccn_charbuf_append_tt(buf, CCN_DTAG_Signature, CCN_DTAG);
+
+ if (digest_algorithm != NULL) {
+ res |= ccn_charbuf_append_tt(buf, CCN_DTAG_DigestAlgorithm, CCN_DTAG);
+ res |= ccn_charbuf_append_tt(buf, strlen(digest_algorithm), CCN_UDATA);
+ res |= ccn_charbuf_append_string(buf, digest_algorithm);
+ res |= ccn_charbuf_append_closer(buf);
+ }
+
+ if (witness != NULL) {
+ res |= ccn_charbuf_append_tt(buf, CCN_DTAG_Witness, CCN_DTAG);
+ res |= ccn_charbuf_append_tt(buf, witness_size, CCN_BLOB);
+ res |= ccn_charbuf_append(buf, witness, witness_size);
+ res |= ccn_charbuf_append_closer(buf);
+ }
+
+ res |= ccn_charbuf_append_tt(buf, CCN_DTAG_SignatureBits, CCN_DTAG);
+ res |= ccn_charbuf_append_tt(buf, signature_size, CCN_BLOB);
+ res |= ccn_charbuf_append(buf, signature, signature_size);
+ res |= ccn_charbuf_append_closer(buf);
+
+ res |= ccn_charbuf_append_closer(buf);
+
+ return(res == 0 ? 0 : -1);
+}
+
+static int
+ccn_pack_ContentObject(struct ccn_charbuf *buf,
+ const struct ccn_charbuf *Name,
+ const struct ccn_charbuf *SignedInfo,
+ const void *data,
+ size_t size,
+ const char *digest_algorithm,
+ const struct ccn_pkey *private_key
+ )
+{
+ int res = 0;
+ struct ccn_sigc *sig_ctx;
+ struct ccn_signature *signature;
+ struct ccn_charbuf *content_header;
+ size_t closer_start;
+
+ content_header = ccn_charbuf_create();
+ res |= ccn_charbuf_append_tt(content_header, CCN_DTAG_Content, CCN_DTAG);
+ if (size != 0)
+ res |= ccn_charbuf_append_tt(content_header, size, CCN_BLOB);
+ closer_start = content_header->length;
+ res |= ccn_charbuf_append_closer(content_header);
+ if (res < 0)
+ return(-1);
+ sig_ctx = ccn_sigc_create();
+ size_t sig_size = ccn_sigc_signature_max_size(sig_ctx, private_key);
+ signature = (ccn_signature *)calloc(1, sig_size);
+ ccn_sigc_destroy(&sig_ctx);
+ res |= ccn_charbuf_append_tt(buf, CCN_DTAG_ContentObject, CCN_DTAG);
+
+ res |= ccn_encode_Signature(buf, digest_algorithm,
+ NULL, 0, signature, sig_size);
+ res |= ccn_charbuf_append_charbuf(buf, Name);
+ res |= ccn_charbuf_append_charbuf(buf, SignedInfo);
+ res |= ccnb_append_tagged_blob(buf, CCN_DTAG_Content, data, size);
+ res |= ccn_charbuf_append_closer(buf);
+ free(signature);
+ ccn_charbuf_destroy(&content_header);
+ return(res == 0 ? 0 : -1);
+}
+
CcnxWrapper::CcnxWrapper()
: m_handle (0)
, m_running (true)
, m_connected (false)
, m_executor (new Executor(1))
+ , m_keystore(NULL)
{
start ();
}
@@ -81,6 +162,10 @@
CcnxWrapper::~CcnxWrapper()
{
shutdown ();
+ if (m_keystore != NULL)
+ {
+ ccn_keystore_destroy(&m_keystore);
+ }
}
void
@@ -271,6 +356,58 @@
return publishData(name, head(content), content.size(), freshness);
}
+int
+CcnxWrapper::publishUnsignedData(const Name &name, const Bytes &content, int freshness)
+{
+ return publishUnsignedData(name, head(content), content.size(), freshness);
+}
+
+int
+CcnxWrapper::publishUnsignedData(const Name &name, const unsigned char *buf, size_t len, int freshness)
+{
+ {
+ UniqueRecLock lock(m_mutex);
+ if (!m_running || !m_connected)
+ {
+ _LOG_TRACE ("<< not running or connected");
+ return -1;
+ }
+ }
+
+ CcnxCharbufPtr ptr = name.toCcnxCharbuf();
+ ccn_charbuf *pname = ptr->getBuf();
+ ccn_charbuf *content = ccn_charbuf_create();
+ ccn_charbuf *signed_info = ccn_charbuf_create();
+
+ if (m_keystore == NULL)
+ {
+ m_keystore = ccn_keystore_create ();
+ string keystoreFile = string(getenv("HOME")) + string("/.ccnx/.ccnx_keystore");
+ if (ccn_keystore_init (m_keystore, (char *)keystoreFile.c_str(), (char*)"Th1s1sn0t8g00dp8ssw0rd.") < 0)
+ BOOST_THROW_EXCEPTION(CcnxOperationException() << errmsg_info_str(keystoreFile.c_str()));
+ }
+
+ int res = ccn_signed_info_create(signed_info,
+ ccn_keystore_public_key_digest(m_keystore),
+ ccn_keystore_public_key_digest_length(m_keystore),
+ NULL,
+ CCN_CONTENT_DATA,
+ freshness,
+ NULL,
+ NULL
+ );
+
+ ccn_pack_ContentObject(content, pname, signed_info, buf, len, NULL, ccn_keystore_private_key (m_keystore));
+
+ Bytes bytes;
+ readRaw(bytes, content->buf, content->length);
+
+ ccn_charbuf_destroy (&content);
+ ccn_charbuf_destroy (&signed_info);
+
+ return putToCcnd (bytes);
+}
+
static void
deleterInInterestTuple (tuple<CcnxWrapper::InterestCallback *, ExecutorPtr> *tuple)
@@ -352,6 +489,10 @@
_LOG_TRACE (">> incomingData content upcall: " << Name (info->content_ccnb, info->content_comps));
break;
+ case CCN_UPCALL_CONTENT_UNVERIFIED:
+ _LOG_TRACE (">> incomingData content unverified upcall: " << Name (info->content_ccnb, info->content_comps));
+ break;
+
case CCN_UPCALL_INTEREST_TIMED_OUT: {
if (cp != NULL)
{
@@ -367,6 +508,7 @@
}
default:
+ _LOG_TRACE(">> unknown upcall type");
return CCN_UPCALL_RESULT_OK;
}
diff --git a/ccnx/ccnx-wrapper.h b/ccnx/ccnx-wrapper.h
index b264d14..6cd1791 100644
--- a/ccnx/ccnx-wrapper.h
+++ b/ccnx/ccnx-wrapper.h
@@ -71,6 +71,12 @@
int
publishData (const Name &name, const Bytes &content, int freshness = DEFAULT_FRESHNESS/* max value for ccnx*/);
+ int
+ publishUnsignedData(const Name &name, const Bytes &content, int freshness = DEFAULT_FRESHNESS);
+
+ int
+ publishUnsignedData(const Name &name, const unsigned char *buf, size_t len, int freshness = DEFAULT_FRESHNESS);
+
static Name
getLocalPrefix ();
@@ -108,6 +114,7 @@
bool m_connected;
std::map<Name, InterestCallback> m_registeredInterests;
ExecutorPtr m_executor;
+ ccn_keystore *m_keystore;
};
typedef boost::shared_ptr<CcnxWrapper> CcnxWrapperPtr;
diff --git a/src/content-server.cc b/src/content-server.cc
index fa0ea4c..c84c6b6 100644
--- a/src/content-server.cc
+++ b/src/content-server.cc
@@ -38,7 +38,7 @@
ContentServer::ContentServer(CcnxWrapperPtr ccnx, ActionLogPtr actionLog,
const boost::filesystem::path &rootDir,
- const Ccnx::Name &deviceName, const std::string &sharedFolderName,
+ const Ccnx::Name &userName, const std::string &sharedFolderName,
const std::string &appName,
int freshness)
: m_ccnx(ccnx)
@@ -46,7 +46,7 @@
, m_dbFolder(rootDir / ".chronoshare")
, m_freshness(freshness)
, m_scheduler (new Scheduler())
- , m_deviceName (deviceName)
+ , m_userName (userName)
, m_sharedFolderName (sharedFolderName)
, m_appName (appName)
{
@@ -60,9 +60,9 @@
m_scheduler->shutdown ();
ScopedLock lock (m_mutex);
- for (PrefixIt it = m_prefixes.begin(); it != m_prefixes.end(); ++it)
+ for (PrefixIt forwardingHint = m_prefixes.begin(); forwardingHint != m_prefixes.end(); ++forwardingHint)
{
- m_ccnx->clearInterestFilter (*it);
+ m_ccnx->clearInterestFilter (*forwardingHint);
}
m_prefixes.clear ();
@@ -75,6 +75,7 @@
// Format for actions: /<forwarding-hint>/<device_name>/<appname>/action/<shared-folder>/<action-seq>
_LOG_DEBUG (">> content server: register " << forwardingHint);
+
m_ccnx->setInterestFilter (forwardingHint, bind(&ContentServer::filterAndServe, this, forwardingHint, _1));
ScopedLock lock (m_mutex);
@@ -91,13 +92,13 @@
m_prefixes.erase (forwardingHint);
}
-void
-ContentServer::filterAndServe (Name forwardingHint, const Name &interest)
-{
- // Format for files: /<forwarding-hint>/<device_name>/<appname>/file/<hash>/<segment>
- // Format for actions: /<forwarding-hint>/<device_name>/<appname>/action/<shared-folder>/<action-seq>
- Name name = interest.getPartialName (forwardingHint.size());
+void
+ContentServer::filterAndServeImpl (const Name &forwardingHint, const Name &name, const Name &interest)
+{
+ // interest for files: /<forwarding-hint>/<device_name>/<appname>/file/<hash>/<segment>
+ // interest for actions: /<forwarding-hint>/<device_name>/<appname>/action/<shared-folder>/<action-seq>
+
// name for files: /<device_name>/<appname>/file/<hash>/<segment>
// name for actions: /<device_name>/<appname>/action/<shared-folder>/<action-seq>
@@ -106,39 +107,50 @@
string type = name.getCompFromBackAsString (2);
if (type == "file")
{
- serve_File (forwardingHint, interest);
+ serve_File (forwardingHint, name, interest);
}
else if (type == "action")
{
- serve_Action (forwardingHint, interest);
+ serve_Action (forwardingHint, name, interest);
}
}
}
void
-ContentServer::serve_Action (Name forwardingHint, Name interest)
+ContentServer::filterAndServe (Name forwardingHint, const Name &interest)
+{
+ if (forwardingHint.size () > 0 &&
+ m_userName.size () >= forwardingHint.size () &&
+ m_userName.getPartialName (0, forwardingHint.size ()) == forwardingHint)
+ {
+ filterAndServeImpl (Name ("/"), interest, interest); // try without forwarding hints
+ }
+
+ filterAndServeImpl (forwardingHint, interest.getPartialName (forwardingHint.size()), interest); // always try with hint... :( have to
+}
+
+void
+ContentServer::serve_Action (const Name &forwardingHint, const Name &name, const Name &interest)
{
_LOG_DEBUG (">> content server serving ACTION, hint: " << forwardingHint << ", interest: " << interest);
- m_scheduler->scheduleOneTimeTask (m_scheduler, 0, bind (&ContentServer::serve_Action_Execute, this, forwardingHint, interest), boost::lexical_cast<string>(interest));
+ m_scheduler->scheduleOneTimeTask (m_scheduler, 0, bind (&ContentServer::serve_Action_Execute, this, forwardingHint, name, interest), boost::lexical_cast<string>(name));
// need to unlock ccnx mutex... or at least don't lock it
}
void
-ContentServer::serve_File (Name forwardingHint, Name interest)
+ContentServer::serve_File (const Name &forwardingHint, const Name &name, const Name &interest)
{
_LOG_DEBUG (">> content server serving FILE, hint: " << forwardingHint << ", interest: " << interest);
- m_scheduler->scheduleOneTimeTask (m_scheduler, 0, bind (&ContentServer::serve_File_Execute, this, forwardingHint, interest), boost::lexical_cast<string>(interest));
+ m_scheduler->scheduleOneTimeTask (m_scheduler, 0, bind (&ContentServer::serve_File_Execute, this, forwardingHint, name, interest), boost::lexical_cast<string>(name));
// need to unlock ccnx mutex... or at least don't lock it
}
void
-ContentServer::serve_File_Execute (Name forwardingHint, Name interest)
+ContentServer::serve_File_Execute (const Name &forwardingHint, const Name &name, const Name &interest)
{
// forwardingHint: /<forwarding-hint>
// interest: /<forwarding-hint>/<device_name>/<appname>/file/<hash>/<segment>
-
- Name name = interest.getPartialName (forwardingHint.size());
// name: /<device_name>/<appname>/file/<hash>/<segment>
int64_t segment = name.getCompFromBackAsInt (0);
@@ -204,12 +216,10 @@
}
void
-ContentServer::serve_Action_Execute (Name forwardingHint, Name interest)
+ContentServer::serve_Action_Execute (const Name &forwardingHint, const Name &name, const Name &interest)
{
// forwardingHint: /<forwarding-hint>
// interest: /<forwarding-hint>/<device_name>/<appname>/action/<shared-folder>/<action-seq>
-
- Name name = interest.getPartialName (forwardingHint.size());
// name for actions: /<device_name>/<appname>/action/<shared-folder>/<action-seq>
int64_t seqno = name.getCompFromBackAsInt (0);
diff --git a/src/content-server.h b/src/content-server.h
index 13ca2dc..55037b7 100644
--- a/src/content-server.h
+++ b/src/content-server.h
@@ -35,7 +35,7 @@
{
public:
ContentServer(Ccnx::CcnxWrapperPtr ccnx, ActionLogPtr actionLog, const boost::filesystem::path &rootDir,
- const Ccnx::Name &deviceName, const std::string &sharedFolderName, const std::string &appName,
+ const Ccnx::Name &userName, const std::string &sharedFolderName, const std::string &appName,
int freshness = -1);
~ContentServer();
@@ -51,16 +51,19 @@
filterAndServe (Ccnx::Name forwardingHint, const Ccnx::Name &interest);
void
- serve_Action (Ccnx::Name forwardingHint, Ccnx::Name interest);
+ filterAndServeImpl (const Ccnx::Name &forwardingHint, const Ccnx::Name &name, const Ccnx::Name &interest);
void
- serve_File (Ccnx::Name forwardingHint, Ccnx::Name interest);
+ serve_Action (const Ccnx::Name &forwardingHint, const Ccnx::Name &name, const Ccnx::Name &interest);
void
- serve_Action_Execute(Ccnx::Name forwardingHint, Ccnx::Name interest);
+ serve_File (const Ccnx::Name &forwardingHint, const Ccnx::Name &name, const Ccnx::Name &interest);
void
- serve_File_Execute(Ccnx::Name forwardingHint, Ccnx::Name interest);
+ serve_Action_Execute(const Ccnx::Name &forwardingHint, const Ccnx::Name &name, const Ccnx::Name &interest);
+
+ void
+ serve_File_Execute(const Ccnx::Name &forwardingHint, const Ccnx::Name &name, const Ccnx::Name &interest);
void
flushStaleDbCache();
@@ -82,7 +85,7 @@
DbCache m_dbCache;
Mutex m_dbCacheMutex;
- Ccnx::Name m_deviceName;
+ Ccnx::Name m_userName;
std::string m_sharedFolderName;
std::string m_appName;
};
diff --git a/src/sync-core.cc b/src/sync-core.cc
index e6a4b01..17cb16d 100644
--- a/src/sync-core.cc
+++ b/src/sync-core.cc
@@ -74,12 +74,6 @@
}
void
-SyncCore::updateLocalPrefix (const Name &localPrefix)
-{
- m_log->UpdateLocalLocator (localPrefix);
-}
-
-void
SyncCore::updateLocalState(sqlite3_int64 seqno)
{
m_log->UpdateLocalSeqNo (seqno);
diff --git a/src/sync-core.h b/src/sync-core.h
index c2b427b..7cf4368 100644
--- a/src/sync-core.h
+++ b/src/sync-core.h
@@ -51,9 +51,6 @@
~SyncCore();
void
- updateLocalPrefix (const Ccnx::Name &localPrefix);
-
- void
localStateChanged ();
/**
diff --git a/src/sync-log.cc b/src/sync-log.cc
index 74506c6..5bd5703 100644
--- a/src/sync-log.cc
+++ b/src/sync-log.cc
@@ -367,12 +367,19 @@
}
void
-SyncLog::UpdateLocalLocator (const Ccnx::Name &locator)
+SyncLog::UpdateLocalLocator (const Ccnx::Name &forwardingHint)
{
- return UpdateLocator (m_localName, locator);
+ if (m_localName.size () >= forwardingHint.size () &&
+ m_localName.getPartialName (0, forwardingHint.size ()) == forwardingHint)
+ {
+ return UpdateLocator (m_localName, Name ("/")); // "directly" accesible
+ }
+ else
+ {
+ return UpdateLocator (m_localName, forwardingHint);
+ }
}
-
SyncStateMsgPtr
SyncLog::FindStateDifferences (const std::string &oldHash, const std::string &newHash, bool includeOldSeq)
{
diff --git a/test/test-ccnx-wrapper.cc b/test/test-ccnx-wrapper.cc
index 2b99dd3..def7876 100644
--- a/test/test-ccnx-wrapper.cc
+++ b/test/test-ccnx-wrapper.cc
@@ -55,6 +55,7 @@
void dataCallback(const Name &name, Ccnx::PcoPtr pco)
{
+ cout << " in data callback" << endl;
BytesPtr content = pco->contentPtr ();
string msg(reinterpret_cast<const char *> (head (*content)), content->size());
g_dataCallback_counter ++;
@@ -67,11 +68,36 @@
g_timeout_counter ++;
}
+void
+setup()
+{
+ if (!c1)
+ {
+ c1 = make_shared<CcnxWrapper> ();
+ }
+ if (!c2)
+ {
+ c2 = make_shared<CcnxWrapper> ();
+ }
+}
+
+void
+teardown()
+{
+ if (c1)
+ {
+ c1.reset();
+ }
+ if (c2)
+ {
+ c2.reset();
+ }
+}
+
+
BOOST_AUTO_TEST_CASE (BlaCcnxWrapperTest)
{
- c1 = make_shared<CcnxWrapper> ();
- c2 = make_shared<CcnxWrapper> ();
-
+ setup();
Name prefix1("/c1");
Name prefix2("/c2");
@@ -89,11 +115,14 @@
// reset
g_dataCallback_counter = 0;
g_timeout_counter = 0;
+
+ teardown();
}
BOOST_AUTO_TEST_CASE (CcnxWrapperSelector)
{
+ setup();
Closure closure (bind(dataCallback, _1, _2), bind(timeout, _1, _2, _3));
Selectors selectors;
@@ -120,6 +149,7 @@
g_dataCallback_counter = 0;
g_timeout_counter = 0;
+ teardown();
}
@@ -132,6 +162,7 @@
BOOST_AUTO_TEST_CASE (TestTimeout)
{
+ setup();
g_dataCallback_counter = 0;
g_timeout_counter = 0;
Closure closure (bind(dataCallback, _1, _2), bind(reexpress, _1, _2, _3));
@@ -146,37 +177,50 @@
usleep(1000);
BOOST_CHECK_EQUAL(g_dataCallback_counter, 1);
BOOST_CHECK_EQUAL(g_timeout_counter, 3);
+ teardown();
}
-BOOST_AUTO_TEST_CASE(Cleanup)
+BOOST_AUTO_TEST_CASE (TestUnsigned)
{
- c1.reset ();
- c2.reset ();
+ setup();
+ string n1 = "/xxxxxx/unsigned/01";
+ Closure closure (bind(dataCallback, _1, _2), bind(timeout, _1, _2, _3));
+
+ g_dataCallback_counter = 0;
+ c1->sendInterest(Name(n1), closure);
+ usleep(1000);
+ c2->publishUnsignedData(Name(n1), (const unsigned char *)n1.c_str(), n1.size(), 1);
+ usleep(1000);
+ BOOST_CHECK_EQUAL(g_dataCallback_counter, 1);
+ teardown();
}
-// BOOST_AUTO_TEST_CASE (CcnxWrapperSigningTest)
-// {
-// Bytes data;
-// data.resize(1024);
-// for (int i = 0; i < 1024; i++)
-// {
-// data[i] = 'm';
-// }
-// Name name("/signingtest");
+ BOOST_AUTO_TEST_CASE (CcnxWrapperUnsigningTest)
+ {
+ setup();
+ Bytes data;
+ data.resize(1024);
+ for (int i = 0; i < 1024; i++)
+ {
+ data[i] = 'm';
+ }
-// posix_time::ptime start = posix_time::second_clock::local_time();
-// for (uint64_t i = 0; i < 10000; i++)
-// {
-// Name n = name;
-// n.appendComp(i);
-// c1->publishData(n, data, 10);
-// }
-// posix_time::ptime end = posix_time::second_clock::local_time();
+ Name name("/unsigningtest");
-// posix_time::time_duration duration = end - start;
+ posix_time::ptime start = posix_time::second_clock::local_time();
+ for (uint64_t i = 0; i < 100000; i++)
+ {
+ Name n = name;
+ n.appendComp(i);
+ c1->publishUnsignedData(n, data, 10);
+ }
+ posix_time::ptime end = posix_time::second_clock::local_time();
-// cout << "Publishing 10000 1K size content objects costs " <<duration.total_milliseconds() << " milliseconds" << endl;
-// cout << "Average time to publish one content object is " << (double) duration.total_milliseconds() / 10000.0 << " milliseconds" << endl;
-// }
+ posix_time::time_duration duration = end - start;
+
+ cout << "Publishing 100000 1K size content objects costs " <<duration.total_milliseconds() << " milliseconds" << endl;
+ cout << "Average time to publish one content object is " << (double) duration.total_milliseconds() / 100000.0 << " milliseconds" << endl;
+ teardown();
+ }
BOOST_AUTO_TEST_SUITE_END()
diff --git a/test/test-fs-watcher.cc b/test/test-fs-watcher.cc
index 10e7b95..92fb516 100644
--- a/test/test-fs-watcher.cc
+++ b/test/test-fs-watcher.cc
@@ -13,7 +13,7 @@
using namespace boost;
namespace fs = boost::filesystem;
-BOOST_AUTO_TEST_SUITE(FsWatcherTests)
+BOOST_AUTO_TEST_SUITE(TestFsWatcher)
void
onChange(set<string> &files, const fs::path &file)
@@ -173,7 +173,35 @@
BOOST_CHECK(files.find(filename) != files.end());
}
+ create_file(dir / "add-removal-check.txt", "add-removal-check");
+ usleep(1200000);
+ BOOST_CHECK (files.find("add-removal-check.txt") != files.end());
+ fs::remove (dir / "add-removal-check.txt");
+ usleep(1200000);
+ BOOST_CHECK (files.find("add-removal-check.txt") == files.end());
+
+ create_file(dir / "add-removal-check.txt", "add-removal-check");
+ usleep(1200000);
+ BOOST_CHECK (files.find("add-removal-check.txt") != files.end());
+
+ fs::remove (dir / "add-removal-check.txt");
+ usleep(1200000);
+ BOOST_CHECK (files.find("add-removal-check.txt") == files.end());
+
+ create_file(dir / "add-removal-check.txt", "add-removal-check");
+ usleep(1200000);
+ BOOST_CHECK (files.find("add-removal-check.txt") != files.end());
+
+ fs::remove (dir / "add-removal-check.txt");
+ usleep(1200000);
+ BOOST_CHECK (files.find("add-removal-check.txt") == files.end());
+
+ // cleanup
+ if (fs::exists(dir))
+ {
+ fs::remove_all(dir);
+ }
}
BOOST_AUTO_TEST_SUITE_END()