blob: d3184d2a36bf6e109bff5bb685477da27731d3d2 [file] [log] [blame]
Yingdi Yu31ad44c2014-08-28 14:55:42 -07001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
2/*
Alexander Afanasyev36eb3ed2017-01-11 12:35:58 -08003 * Copyright (c) 2012-2017 University of California, Los Angeles
Yingdi Yu31ad44c2014-08-28 14:55:42 -07004 *
5 * This file is part of ChronoSync, synchronization library for distributed realtime
6 * applications for NDN.
7 *
8 * 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.
11 *
12 * 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.
15 *
16 * 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 Zhenkai Zhu <http://irl.cs.ucla.edu/~zhenkai/>
20 * @author Chaoyi Bian <bcy@pku.edu.cn>
21 * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
22 * @author Yingdi Yu <yingdi@cs.ucla.edu>
23 */
24
25#include "socket.hpp"
26#include "logger.hpp"
27
Alexander Afanasyev36eb3ed2017-01-11 12:35:58 -080028INIT_LOGGER(Socket);
Yingdi Yu31ad44c2014-08-28 14:55:42 -070029
Yingdi Yu31ad44c2014-08-28 14:55:42 -070030namespace chronosync {
31
Yingdi Yucd339022014-11-05 17:51:19 -080032const ndn::Name Socket::DEFAULT_NAME;
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -080033const ndn::Name Socket::DEFAULT_PREFIX;
Ashlesh Gawande08784d42017-09-06 23:40:21 -050034const std::shared_ptr<Validator> Socket::DEFAULT_VALIDATOR;
Yingdi Yucd339022014-11-05 17:51:19 -080035
Yingdi Yu31ad44c2014-08-28 14:55:42 -070036Socket::Socket(const Name& syncPrefix,
37 const Name& userPrefix,
38 ndn::Face& face,
Yingdi Yucd339022014-11-05 17:51:19 -080039 const UpdateCallback& updateCallback,
40 const Name& signingId,
Ashlesh Gawande08784d42017-09-06 23:40:21 -050041 std::shared_ptr<Validator> validator)
Yingdi Yu31ad44c2014-08-28 14:55:42 -070042 : m_userPrefix(userPrefix)
43 , m_face(face)
Yingdi Yucd339022014-11-05 17:51:19 -080044 , m_logic(face, syncPrefix, userPrefix, updateCallback)
45 , m_signingId(signingId)
46 , m_validator(validator)
Yingdi Yu31ad44c2014-08-28 14:55:42 -070047{
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -080048 if (m_userPrefix != DEFAULT_NAME)
49 m_registeredPrefixList[m_userPrefix] =
50 m_face.setInterestFilter(m_userPrefix,
51 bind(&Socket::onInterest, this, _1, _2),
52 [] (const Name& prefix, const std::string& msg) {});
Yingdi Yu31ad44c2014-08-28 14:55:42 -070053}
54
Qiuhan Ding03b9de32015-01-30 14:03:12 -080055Socket::~Socket()
56{
57 for(const auto& itr : m_registeredPrefixList) {
58 if (static_cast<bool>(itr.second))
59 m_face.unsetInterestFilter(itr.second);
60 }
61 m_ims.erase("/");
62}
63
Yingdi Yu31ad44c2014-08-28 14:55:42 -070064void
Qiuhan Dinge246b622014-12-03 21:57:48 -080065Socket::addSyncNode(const Name& prefix, const Name& signingId)
Yingdi Yu31ad44c2014-08-28 14:55:42 -070066{
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -080067 if (prefix == DEFAULT_NAME)
68 return;
69
70 auto itr = m_registeredPrefixList.find(prefix);
71 if (itr != m_registeredPrefixList.end())
72 return;
73
74 if (m_userPrefix == DEFAULT_NAME)
75 m_userPrefix = prefix;
Qiuhan Dinge246b622014-12-03 21:57:48 -080076 m_logic.addUserNode(prefix, signingId);
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -080077 m_registeredPrefixList[prefix] =
78 m_face.setInterestFilter(prefix,
79 bind(&Socket::onInterest, this, _1, _2),
80 [] (const Name& prefix, const std::string& msg) {});
Yingdi Yu31ad44c2014-08-28 14:55:42 -070081}
82
83void
Qiuhan Ding03b9de32015-01-30 14:03:12 -080084Socket::removeSyncNode(const Name& prefix)
85{
86 if (prefix == DEFAULT_NAME)
87 return;
88
89 auto itr = m_registeredPrefixList.find(prefix);
90 if (itr != m_registeredPrefixList.end()) {
91 if (static_cast<bool>(itr->second))
92 m_face.unsetInterestFilter(itr->second);
93 m_registeredPrefixList.erase(itr);
94 }
95
96 m_ims.erase(prefix);
97 m_logic.removeUserNode(prefix);
98
99}
100
101void
Qiuhan Dinge246b622014-12-03 21:57:48 -0800102Socket::publishData(const uint8_t* buf, size_t len, const ndn::time::milliseconds& freshness,
103 const Name& prefix)
104{
Junxiao Shi60d25882016-07-23 01:41:30 +0000105 publishData(ndn::encoding::makeBinaryBlock(ndn::tlv::Content, buf, len), freshness, prefix);
Qiuhan Dinge246b622014-12-03 21:57:48 -0800106}
107
108void
Ashlesh Gawande8d1347a2017-04-03 19:10:28 -0500109Socket::publishData(const uint8_t* buf, size_t len, const ndn::time::milliseconds& freshness,
110 const uint64_t& seqNo, const Name& prefix)
111{
112 publishData(ndn::encoding::makeBinaryBlock(ndn::tlv::Content, buf, len), freshness, seqNo, prefix);
113}
114
115void
Qiuhan Dinge246b622014-12-03 21:57:48 -0800116Socket::publishData(const Block& content, const ndn::time::milliseconds& freshness,
117 const Name& prefix)
Yingdi Yu31ad44c2014-08-28 14:55:42 -0700118{
119 shared_ptr<Data> data = make_shared<Data>();
120 data->setContent(content);
121 data->setFreshnessPeriod(freshness);
122
Qiuhan Dinge246b622014-12-03 21:57:48 -0800123 SeqNo newSeq = m_logic.getSeqNo(prefix) + 1;
Yingdi Yu31ad44c2014-08-28 14:55:42 -0700124 Name dataName;
Qiuhan Dinge246b622014-12-03 21:57:48 -0800125 dataName.append(m_logic.getSessionName(prefix)).appendNumber(newSeq);
Yingdi Yu31ad44c2014-08-28 14:55:42 -0700126 data->setName(dataName);
127
Yingdi Yucd339022014-11-05 17:51:19 -0800128 if (m_signingId.empty())
129 m_keyChain.sign(*data);
130 else
Ashlesh Gawande687cf922017-05-30 15:04:16 -0500131 m_keyChain.sign(*data, security::signingByIdentity(m_signingId));
Yingdi Yu31ad44c2014-08-28 14:55:42 -0700132
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800133 m_ims.insert(*data);
Yingdi Yu31ad44c2014-08-28 14:55:42 -0700134
Qiuhan Dinge246b622014-12-03 21:57:48 -0800135 m_logic.updateSeqNo(newSeq, prefix);
Yingdi Yu31ad44c2014-08-28 14:55:42 -0700136}
137
138void
Ashlesh Gawande8d1347a2017-04-03 19:10:28 -0500139Socket::publishData(const Block& content, const ndn::time::milliseconds& freshness,
140 const uint64_t& seqNo, const Name& prefix)
141{
142 shared_ptr<Data> data = make_shared<Data>();
143 data->setContent(content);
144 data->setFreshnessPeriod(freshness);
145
146 SeqNo newSeq = seqNo;
147 Name dataName;
148 dataName.append(m_logic.getSessionName(prefix)).appendNumber(newSeq);
149 data->setName(dataName);
150
151 if (m_signingId.empty())
152 m_keyChain.sign(*data);
153 else
Ashlesh Gawande687cf922017-05-30 15:04:16 -0500154 m_keyChain.sign(*data, security::signingByIdentity(m_signingId));
Ashlesh Gawande8d1347a2017-04-03 19:10:28 -0500155
156 m_ims.insert(*data);
157
158 m_logic.updateSeqNo(newSeq, prefix);
159}
160
161void
Yingdi Yu31ad44c2014-08-28 14:55:42 -0700162Socket::fetchData(const Name& sessionName, const SeqNo& seqNo,
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500163 const DataValidatedCallback& dataCallback,
Yingdi Yu31ad44c2014-08-28 14:55:42 -0700164 int nRetries)
165{
166 Name interestName;
167 interestName.append(sessionName).appendNumber(seqNo);
168
169 Interest interest(interestName);
170 interest.setMustBeFresh(true);
171
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500172 DataValidationErrorCallback failureCallback =
Yingdi Yu31ad44c2014-08-28 14:55:42 -0700173 bind(&Socket::onDataValidationFailed, this, _1, _2);
174
175 m_face.expressInterest(interest,
176 bind(&Socket::onData, this, _1, _2, dataCallback, failureCallback),
177 bind(&Socket::onDataTimeout, this, _1, nRetries,
Alexander Afanasyeve9eda8a2017-03-09 14:40:03 -0800178 dataCallback, failureCallback), // Nack
179 bind(&Socket::onDataTimeout, this, _1, nRetries,
Yingdi Yu31ad44c2014-08-28 14:55:42 -0700180 dataCallback, failureCallback));
181}
182
183void
184Socket::fetchData(const Name& sessionName, const SeqNo& seqNo,
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500185 const DataValidatedCallback& dataCallback,
186 const DataValidationErrorCallback& failureCallback,
Alexander Afanasyeve9eda8a2017-03-09 14:40:03 -0800187 const ndn::TimeoutCallback& onTimeout,
Yingdi Yu31ad44c2014-08-28 14:55:42 -0700188 int nRetries)
189{
190 _LOG_DEBUG(">> Socket::fetchData");
191 Name interestName;
192 interestName.append(sessionName).appendNumber(seqNo);
193
194 Interest interest(interestName);
195 interest.setMustBeFresh(true);
196
197 m_face.expressInterest(interest,
198 bind(&Socket::onData, this, _1, _2, dataCallback, failureCallback),
Alexander Afanasyeve9eda8a2017-03-09 14:40:03 -0800199 bind(onTimeout, _1), // Nack
Yingdi Yu31ad44c2014-08-28 14:55:42 -0700200 onTimeout);
201
202 _LOG_DEBUG("<< Socket::fetchData");
203}
204
205void
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800206Socket::onInterest(const Name& prefix, const Interest& interest)
207{
208 shared_ptr<const Data>data = m_ims.find(interest);
209 if (static_cast<bool>(data)) {
210 m_face.put(*data);
211 }
212}
213
214void
Alexander Afanasyeve9eda8a2017-03-09 14:40:03 -0800215Socket::onData(const Interest& interest, const Data& data,
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500216 const DataValidatedCallback& onValidated,
217 const DataValidationErrorCallback& onFailed)
Yingdi Yu31ad44c2014-08-28 14:55:42 -0700218{
219 _LOG_DEBUG("Socket::onData");
Yingdi Yucd339022014-11-05 17:51:19 -0800220
221 if (static_cast<bool>(m_validator))
222 m_validator->validate(data, onValidated, onFailed);
223 else
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500224 onValidated(data);
Yingdi Yu31ad44c2014-08-28 14:55:42 -0700225}
226
227void
228Socket::onDataTimeout(const Interest& interest, int nRetries,
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500229 const DataValidatedCallback& onValidated,
230 const DataValidationErrorCallback& onFailed)
Yingdi Yu31ad44c2014-08-28 14:55:42 -0700231{
232 _LOG_DEBUG("Socket::onDataTimeout");
233 if (nRetries <= 0)
234 return;
235
Ashlesh Gawande8dfa63c2017-07-31 17:01:00 -0500236 Interest newNonceInterest(interest);
237 newNonceInterest.refreshNonce();
238
239 m_face.expressInterest(newNonceInterest,
Yingdi Yu31ad44c2014-08-28 14:55:42 -0700240 bind(&Socket::onData, this, _1, _2, onValidated, onFailed),
241 bind(&Socket::onDataTimeout, this, _1, nRetries - 1,
Alexander Afanasyeve9eda8a2017-03-09 14:40:03 -0800242 onValidated, onFailed), // Nack
243 bind(&Socket::onDataTimeout, this, _1, nRetries - 1,
Yingdi Yu31ad44c2014-08-28 14:55:42 -0700244 onValidated, onFailed));
245}
246
247void
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500248Socket::onDataValidationFailed(const Data& data,
249 const ValidationError& error)
Yingdi Yu31ad44c2014-08-28 14:55:42 -0700250{
251}
252
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500253ConstBufferPtr
Yingdi Yu31ad44c2014-08-28 14:55:42 -0700254Socket::getRootDigest() const
255{
256 return m_logic.getRootDigest();
257}
258
259} // namespace chronosync