blob: 5e66ac66979dee72cbb0366f959060cfbdfa1f25 [file] [log] [blame]
Yingdi Yu43e71612013-10-30 22:19:31 -07001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
2/*
Alexander Afanasyev8722d872014-07-02 13:00:29 -07003 * Copyright (c) 2012-2014 University of California, Los Angeles
Yingdi Yu43e71612013-10-30 22:19:31 -07004 *
Alexander Afanasyev8722d872014-07-02 13:00:29 -07005 * This file is part of ChronoSync, synchronization library for distributed realtime
6 * applications for NDN.
Yingdi Yu43e71612013-10-30 22:19:31 -07007 *
Alexander Afanasyev8722d872014-07-02 13:00:29 -07008 * ChronoSync is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation, either
10 * version 3 of the License, or (at your option) any later version.
Yingdi Yu43e71612013-10-30 22:19:31 -070011 *
Alexander Afanasyev8722d872014-07-02 13:00:29 -070012 * ChronoSync is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
Yingdi Yu43e71612013-10-30 22:19:31 -070015 *
Alexander Afanasyev8722d872014-07-02 13:00:29 -070016 * You should have received a copy of the GNU General Public License along with
17 * ChronoSync, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/web/index.html>
20 * @author Zhenkai Zhu <http://irl.cs.ucla.edu/~zhenkai/>
21 * @author Chaoyi Bian <bcy@pku.edu.cn>
22 * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
Yingdi Yu43e71612013-10-30 22:19:31 -070023 */
24
Alexander Afanasyev531803b2014-02-05 15:57:35 -080025#ifndef _SYNC_SOCKET_H
26#define _SYNC_SOCKET_H
Yingdi Yu280bb962014-01-30 09:52:43 -080027
Yingdi Yu7c64e5c2014-04-30 14:06:37 -070028#include <ndn-cxx/face.hpp>
29#include <ndn-cxx/security/validator.hpp>
30#include <ndn-cxx/security/validator-null.hpp>
31#include <ndn-cxx/security/key-chain.hpp>
Yingdi Yu280bb962014-01-30 09:52:43 -080032
Alexander Afanasyev531803b2014-02-05 15:57:35 -080033#include "sync-logic.h"
34#include "sync-seq-no.h"
Yingdi Yu3da10fe2014-02-27 16:37:34 -080035#include "sync-validator.h"
Alexander Afanasyev531803b2014-02-05 15:57:35 -080036
Yingdi Yu43e71612013-10-30 22:19:31 -070037#include <utility>
38#include <map>
39#include <vector>
40#include <sstream>
41
42namespace Sync {
43
44/**
45 * \ingroup sync
46 * @brief A simple interface to interact with client code
47 */
48class SyncSocket
49{
50public:
Yingdi Yuaed0f3e2014-02-28 14:54:16 -080051 struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
52
Yingdi Yu280bb962014-01-30 09:52:43 -080053 typedef ndn::function< void (const std::vector<MissingDataInfo> &, SyncSocket * ) > NewDataCallback;
54 typedef ndn::function< void (const std::string &/*prefix*/ ) > RemoveCallback;
55
Yingdi Yud4ef5d32014-03-01 02:02:01 -080056 static const ndn::Name EMPTY_NAME;
Yingdi Yu43e71612013-10-30 22:19:31 -070057
Yingdi Yu7c64e5c2014-04-30 14:06:37 -070058 SyncSocket(const ndn::Name& syncPrefix,
Yingdi Yud4ef5d32014-03-01 02:02:01 -080059 const ndn::Name& dataPrefix,
60 uint64_t dataSession,
61 bool withRoutingPrefix,
62 const ndn::Name& routingPrefix,
63 ndn::shared_ptr<ndn::Face> face,
64 const ndn::IdentityCertificate& myCertificate,
65 ndn::shared_ptr<ndn::SecRuleRelative> dataRule,
Yingdi Yu7c64e5c2014-04-30 14:06:37 -070066 NewDataCallback dataCallback,
Yingdi Yud4ef5d32014-03-01 02:02:01 -080067 RemoveCallback rmCallback);
68
69 ~SyncSocket();
Yingdi Yu43e71612013-10-30 22:19:31 -070070
Yingdi Yu3da10fe2014-02-27 16:37:34 -080071 void
72 publishData(const uint8_t* buf, size_t len, int freshness, bool isCert = false);
Yingdi Yu43e71612013-10-30 22:19:31 -070073
Yingdi Yu7c64e5c2014-04-30 14:06:37 -070074 void
75 leave()
76 {
77 m_syncLogic->remove(m_withRoutingPrefix ? m_routableDataPrefix : m_dataPrefix);
Yingdi Yud4ef5d32014-03-01 02:02:01 -080078 }
79
80 void
81 remove(const ndn::Name& prefix)
82 {
83 m_syncLogic->remove(prefix);
Yingdi Yu3da10fe2014-02-27 16:37:34 -080084 }
Yingdi Yu43e71612013-10-30 22:19:31 -070085
Yingdi Yu7c64e5c2014-04-30 14:06:37 -070086 void
Yingdi Yu280bb962014-01-30 09:52:43 -080087 fetchData(const ndn::Name &prefix, const SeqNo &seq, const ndn::OnDataValidated& onValidated, int retry = 0);
Yingdi Yu43e71612013-10-30 22:19:31 -070088
Yingdi Yu7c64e5c2014-04-30 14:06:37 -070089 std::string
90 getRootDigest()
91 {
92 return m_syncLogic->getRootDigest();
Yingdi Yu3da10fe2014-02-27 16:37:34 -080093 }
Yingdi Yu43e71612013-10-30 22:19:31 -070094
Yingdi Yu280bb962014-01-30 09:52:43 -080095 uint64_t
Yingdi Yud4ef5d32014-03-01 02:02:01 -080096 getNextSeq()
Yingdi Yu3da10fe2014-02-27 16:37:34 -080097 {
Yingdi Yud4ef5d32014-03-01 02:02:01 -080098 // If DNS works, we should use pure m_dataprefix rather than the one with routing prefix.
99 SequenceLog::iterator i = m_sequenceLog.find (m_withRoutingPrefix ? m_routableDataPrefix : m_dataPrefix);
Yingdi Yu7c64e5c2014-04-30 14:06:37 -0700100
Yingdi Yu3da10fe2014-02-27 16:37:34 -0800101 if (i != m_sequenceLog.end ())
102 {
103 SeqNo s = i->second;
Yingdi Yud4ef5d32014-03-01 02:02:01 -0800104 if (s.getSession() == m_dataSession)
Yingdi Yu3da10fe2014-02-27 16:37:34 -0800105 return s.getSeq();
106 }
107 return 0;
108 }
Yingdi Yu43e71612013-10-30 22:19:31 -0700109
110 SyncLogic &
Yingdi Yu7c64e5c2014-04-30 14:06:37 -0700111 getLogic()
112 {
113 return *m_syncLogic;
Yingdi Yu3da10fe2014-02-27 16:37:34 -0800114 }
Yingdi Yu43e71612013-10-30 22:19:31 -0700115
Yingdi Yu3da10fe2014-02-27 16:37:34 -0800116 void
117 addParticipant(const ndn::IdentityCertificate& introducee)
118 {
Yingdi Yuaed0f3e2014-02-28 14:54:16 -0800119 if(m_withSecurity)
120 {
121 ndn::dynamic_pointer_cast<SyncValidator>(m_syncValidator)->addParticipant(introducee);
122 }
123 }
124
125 void
126 addParticipant(const IntroCertificate& introCert)
127 {
128 if(m_withSecurity)
129 {
130 ndn::dynamic_pointer_cast<SyncValidator>(m_syncValidator)->addParticipant(introCert);
131 }
132 }
133
134 void
135 getIntroCertNames(std::vector<ndn::Name>& list)
136 {
137 if(m_withSecurity)
138 {
139 ndn::dynamic_pointer_cast<SyncValidator>(m_syncValidator)->getIntroCertNames(list);
140 }
141 }
142
143 const IntroCertificate&
144 getIntroCertificate(const ndn::Name& name)
145 {
146 if(m_withSecurity)
147 {
148 return ndn::dynamic_pointer_cast<SyncValidator>(m_syncValidator)->getIntroCertificate(name);
149 }
150 throw Error("You are running SyncSocket without security!");
Yingdi Yu3da10fe2014-02-27 16:37:34 -0800151 }
152
153 // // make this a static function so we don't have to create socket instance without
154 // // knowing the local prefix. it's a wrong place for this function anyway
155 // static std::string
Yingdi Yu7c64e5c2014-04-30 14:06:37 -0700156 // GetLocalPrefix ();
157
Yingdi Yu43e71612013-10-30 22:19:31 -0700158private:
Yingdi Yu51c80252014-02-10 19:32:05 -0800159 void
Yingdi Yud4ef5d32014-03-01 02:02:01 -0800160 publishDataInternal(ndn::shared_ptr<ndn::Data> data, bool isCert);
Yingdi Yu51c80252014-02-10 19:32:05 -0800161
Yingdi Yu7c64e5c2014-04-30 14:06:37 -0700162 void
163 passCallback(const std::vector<MissingDataInfo> &v)
164 {
165 m_newDataCallback(v, this);
Yingdi Yu3da10fe2014-02-27 16:37:34 -0800166 }
Yingdi Yu43e71612013-10-30 22:19:31 -0700167
168 void
Yingdi Yud4ef5d32014-03-01 02:02:01 -0800169 onData(const ndn::Interest& interest, ndn::Data& data, const ndn::OnDataValidated& dataCallback);
Yingdi Yu46c9f1a2013-12-18 15:15:46 +0800170
171 void
Yingdi Yud4ef5d32014-03-01 02:02:01 -0800172 onDataTimeout(const ndn::Interest& interest, int retry, const ndn::OnDataValidated& dataCallback);
173
Yingdi Yu46c9f1a2013-12-18 15:15:46 +0800174
175 void
Yingdi Yu3da10fe2014-02-27 16:37:34 -0800176 onDataValidated(const ndn::shared_ptr<const ndn::Data>& data,
177 size_t interestNameSize,
178 const ndn::OnDataValidated& onValidated);
179
180 void
181 onDataValidationFailed(const ndn::shared_ptr<const ndn::Data>& data,
182 const std::string& failureInfo);
Yingdi Yu43e71612013-10-30 22:19:31 -0700183
184private:
Yingdi Yu6d638f02014-01-24 11:01:21 -0800185 typedef std::map<ndn::Name, SeqNo> SequenceLog;
Yingdi Yu3da10fe2014-02-27 16:37:34 -0800186
187 ndn::Name m_dataPrefix;
188 uint64_t m_dataSession;
Yingdi Yud4ef5d32014-03-01 02:02:01 -0800189 ndn::Name m_routableDataPrefix;
190 bool m_withRoutingPrefix;
Yingdi Yu43e71612013-10-30 22:19:31 -0700191 NewDataCallback m_newDataCallback;
192 SequenceLog m_sequenceLog;
Yingdi Yu3da10fe2014-02-27 16:37:34 -0800193 ndn::IdentityCertificate m_myCertificate;
194 ndn::KeyChain m_keyChain;
Yingdi Yu280bb962014-01-30 09:52:43 -0800195 ndn::shared_ptr<ndn::Face> m_face;
Alexander Afanasyev7fe59832014-07-02 12:17:46 -0700196 boost::asio::io_service& m_ioService;
Yingdi Yuaed0f3e2014-02-28 14:54:16 -0800197 bool m_withSecurity;
198 ndn::shared_ptr<ndn::Validator> m_syncValidator;
199 ndn::shared_ptr<SyncLogic> m_syncLogic;
Yingdi Yu43e71612013-10-30 22:19:31 -0700200};
201
202} // Sync
203
204#endif // SYNC_SOCKET_H