blob: f5e378fc7b5cf6070872303acc6d9a48f7a23f0b [file] [log] [blame]
Yingdi Yu43e71612013-10-30 22:19:31 -07001/* -*- Mode: C32++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2012 University of California, Los Angeles
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Yingdi Yu <yingdi@cs.ucla.edu>
19 */
20
21#include "sync-socket.h"
Yingdi Yu46c9f1a2013-12-18 15:15:46 +080022#include "sync-logging.h"
23
Yingdi Yu43e71612013-10-30 22:19:31 -070024using namespace ndn;
Yingdi Yu46c9f1a2013-12-18 15:15:46 +080025
26INIT_LOGGER ("SyncSocket");
Yingdi Yu43e71612013-10-30 22:19:31 -070027
28namespace Sync {
29
Alexander Afanasyev531803b2014-02-05 15:57:35 -080030using ndn::shared_ptr;
31
Yingdi Yud4ef5d32014-03-01 02:02:01 -080032static const uint8_t ROUTING_PREFIX_SEPARATOR[2] = {0xF0, 0x2E};
33
34const Name SyncSocket::EMPTY_NAME = Name();
35
Yingdi Yu0eee6002014-02-11 15:54:17 -080036SyncSocket::SyncSocket (const Name& syncPrefix,
Yingdi Yud4ef5d32014-03-01 02:02:01 -080037 const Name& dataPrefix,
Yingdi Yu3da10fe2014-02-27 16:37:34 -080038 uint64_t dataSession,
Yingdi Yud4ef5d32014-03-01 02:02:01 -080039 bool withRoutingPrefix,
40 const Name& routingPrefix,
Yingdi Yuaed0f3e2014-02-28 14:54:16 -080041 shared_ptr<Face> face,
Yingdi Yu3da10fe2014-02-27 16:37:34 -080042 const IdentityCertificate& myCertificate,
43 shared_ptr<SecRuleRelative> dataRule,
Yingdi Yu43e71612013-10-30 22:19:31 -070044 NewDataCallback dataCallback,
45 RemoveCallback rmCallback )
Yingdi Yu3da10fe2014-02-27 16:37:34 -080046 : m_dataPrefix(dataPrefix)
47 , m_dataSession(dataSession)
Yingdi Yud4ef5d32014-03-01 02:02:01 -080048 , m_withRoutingPrefix(false)
Yingdi Yu3da10fe2014-02-27 16:37:34 -080049 , m_newDataCallback(dataCallback)
50 , m_myCertificate(myCertificate)
Yingdi Yu6e235db2013-12-27 08:40:53 +080051 , m_face(face)
Yingdi Yu51c80252014-02-10 19:32:05 -080052 , m_ioService(face->ioService())
Yingdi Yuaed0f3e2014-02-28 14:54:16 -080053{
Yingdi Yud4ef5d32014-03-01 02:02:01 -080054 if(withRoutingPrefix && !routingPrefix.isPrefixOf(m_dataPrefix))
55 {
56 m_withRoutingPrefix = true;
57 m_routableDataPrefix.append(routingPrefix).append(ROUTING_PREFIX_SEPARATOR, 2).append(m_dataPrefix);
58 }
59
60
Yingdi Yuaed0f3e2014-02-28 14:54:16 -080061 if(static_cast<bool>(dataRule))
62 {
63 m_withSecurity = true;
64 m_syncValidator = shared_ptr<Validator>(new SyncValidator(syncPrefix,
65 m_myCertificate,
66 m_face,
67 bind(&SyncSocket::publishData, this, _1, _2, _3, true),
68 dataRule));
69 }
70 else
71 {
72 m_withSecurity = false;
73 m_syncValidator = shared_ptr<Validator>(new ValidatorNull());
74 }
75
76
77 m_syncLogic = shared_ptr<SyncLogic>(new SyncLogic(syncPrefix,
78 myCertificate,
79 m_syncValidator,
80 m_face,
81 bind(&SyncSocket::passCallback, this, _1),
82 rmCallback));
83}
Yingdi Yu43e71612013-10-30 22:19:31 -070084
85SyncSocket::~SyncSocket()
Yingdi Yu479e1172013-11-06 16:36:19 -080086{
Yingdi Yu46c9f1a2013-12-18 15:15:46 +080087}
88
Yingdi Yu3da10fe2014-02-27 16:37:34 -080089void
90SyncSocket::publishData(const uint8_t* buf, size_t len, int freshness, bool isCert)
Yingdi Yu43e71612013-10-30 22:19:31 -070091{
Yingdi Yu51c80252014-02-10 19:32:05 -080092 shared_ptr<Data> data = make_shared<Data>();
93 data->setContent(reinterpret_cast<const uint8_t*>(buf), len);
Yingdi Yu6e1c9cd2014-03-25 10:26:54 -070094 data->setFreshnessPeriod(time::milliseconds(1000*freshness));
Yingdi Yu51c80252014-02-10 19:32:05 -080095
Yingdi Yu3da10fe2014-02-27 16:37:34 -080096 m_ioService->post(bind(&SyncSocket::publishDataInternal, this,
Yingdi Yud4ef5d32014-03-01 02:02:01 -080097 data, isCert));
Yingdi Yu51c80252014-02-10 19:32:05 -080098}
99
100void
Yingdi Yud4ef5d32014-03-01 02:02:01 -0800101SyncSocket::publishDataInternal(shared_ptr<Data> data, bool isCert)
Yingdi Yu51c80252014-02-10 19:32:05 -0800102{
Yingdi Yud4ef5d32014-03-01 02:02:01 -0800103 Name dataPrefix = (m_withRoutingPrefix ? m_routableDataPrefix : m_dataPrefix);
104
105 uint64_t sequence = getNextSeq();
106
107 Name dataName;
108 dataName.append(m_dataPrefix)
Yingdi Yu68bc51a2014-03-25 16:02:12 -0700109 .append(boost::lexical_cast<std::string>(m_dataSession))
110 .append(boost::lexical_cast<std::string>(sequence));
Yingdi Yu3da10fe2014-02-27 16:37:34 -0800111 if(isCert)
112 dataName.append("INTRO-CERT");
Yingdi Yu51c80252014-02-10 19:32:05 -0800113 data->setName(dataName);
Yingdi Yu3da10fe2014-02-27 16:37:34 -0800114 m_keyChain.sign(*data, m_myCertificate.getName());
Yingdi Yu46c9f1a2013-12-18 15:15:46 +0800115
Yingdi Yud4ef5d32014-03-01 02:02:01 -0800116 if(m_withRoutingPrefix)
117 {
118 Name wrappedName;
119 wrappedName.append(m_routableDataPrefix)
Yingdi Yu68bc51a2014-03-25 16:02:12 -0700120 .append(boost::lexical_cast<std::string>(m_dataSession))
121 .append(boost::lexical_cast<std::string>(sequence));
Yingdi Yu51c80252014-02-10 19:32:05 -0800122
Yingdi Yud4ef5d32014-03-01 02:02:01 -0800123 Data wrappedData(wrappedName);
124 wrappedData.setContent(data->wireEncode());
125 m_keyChain.sign(wrappedData, m_myCertificate.getName());
126
127 m_face->put(wrappedData);
128 }
129 else
130 {
131 m_face->put(*data);
132 }
133
134 SeqNo s(m_dataSession, sequence + 1);
135 m_sequenceLog[dataPrefix] = s;
136 m_syncLogic->addLocalNames (dataPrefix, m_dataSession, sequence); // If DNS works, we should use pure m_dataprefix rather than the one with routing prefix.
Yingdi Yu43e71612013-10-30 22:19:31 -0700137}
138
139void
Yingdi Yud4ef5d32014-03-01 02:02:01 -0800140SyncSocket::fetchData(const Name& prefix, const SeqNo& seq, const OnDataValidated& dataCallback, int retry)
Yingdi Yu43e71612013-10-30 22:19:31 -0700141{
Yingdi Yu6d638f02014-01-24 11:01:21 -0800142 Name interestName = prefix;
Yingdi Yu68bc51a2014-03-25 16:02:12 -0700143 interestName.append(boost::lexical_cast<std::string>(seq.getSession())).append(boost::lexical_cast<std::string>(seq.getSeq()));
Yingdi Yu6d638f02014-01-24 11:01:21 -0800144
Yingdi Yu6d638f02014-01-24 11:01:21 -0800145 ndn::Interest interest(interestName);
Yingdi Yu280bb962014-01-30 09:52:43 -0800146 interest.setMustBeFresh(true);
Yingdi Yu3da10fe2014-02-27 16:37:34 -0800147
Yingdi Yud4ef5d32014-03-01 02:02:01 -0800148 m_face->expressInterest(interest,
149 bind(&SyncSocket::onData, this, _1, _2, dataCallback),
150 bind(&SyncSocket::onDataTimeout, this, _1, retry, dataCallback));
151
152}
153
154void
155SyncSocket::onData(const ndn::Interest& interest, Data& data, const OnDataValidated& dataCallback)
156{
157 bool encaped = false;
158
159 Name interestName = interest.getName();
160 Name::const_iterator it = interestName.begin();
161 Name::const_iterator end = interestName.end();
162
163 size_t offset = interestName.size();
164 for(; it != end; it++)
165 {
166 offset--;
167 if(it->toEscapedString() == "%F0.")
168 {
169 encaped = true;
170 break;
171 }
172 }
173
174 if(!encaped)
175 offset = interestName.size();
176
177 const OnDataValidated& onValidated = bind(&SyncSocket::onDataValidated, this, _1, offset, dataCallback);
Yingdi Yu3da10fe2014-02-27 16:37:34 -0800178 const OnDataValidationFailed& onValidationFailed = bind(&SyncSocket::onDataValidationFailed, this, _1, _2);
179
Yingdi Yud4ef5d32014-03-01 02:02:01 -0800180 if(encaped)
181 {
182 shared_ptr<Data> innerData = make_shared<Data>();
183 innerData->wireDecode(data.getContent().blockFromValue());
184 m_syncValidator->validate(*innerData, onValidated, onValidationFailed);
185 }
186 else
187 m_syncValidator->validate(data, onValidated, onValidationFailed);
Yingdi Yu43e71612013-10-30 22:19:31 -0700188}
189
190void
Yingdi Yud4ef5d32014-03-01 02:02:01 -0800191SyncSocket::onDataTimeout(const ndn::Interest& interest, int retry, const OnDataValidated& dataCallback)
Yingdi Yu43e71612013-10-30 22:19:31 -0700192{
193 if(retry > 0)
194 {
Yingdi Yu51c80252014-02-10 19:32:05 -0800195 m_face->expressInterest(interest,
Yingdi Yu6d638f02014-01-24 11:01:21 -0800196 bind(&SyncSocket::onData,
Yingdi Yu46c9f1a2013-12-18 15:15:46 +0800197 this,
198 _1,
199 _2,
Yingdi Yud4ef5d32014-03-01 02:02:01 -0800200 dataCallback),
Yingdi Yu6d638f02014-01-24 11:01:21 -0800201 bind(&SyncSocket::onDataTimeout,
Yingdi Yu46c9f1a2013-12-18 15:15:46 +0800202 this,
203 _1,
204 retry - 1,
Yingdi Yud4ef5d32014-03-01 02:02:01 -0800205 dataCallback));
Yingdi Yu46c9f1a2013-12-18 15:15:46 +0800206
Yingdi Yu43e71612013-10-30 22:19:31 -0700207 }
Yingdi Yu46c9f1a2013-12-18 15:15:46 +0800208 else
Yingdi Yu6d638f02014-01-24 11:01:21 -0800209 _LOG_DEBUG("interest eventually time out!");
Yingdi Yu43e71612013-10-30 22:19:31 -0700210}
211
212void
Yingdi Yu3da10fe2014-02-27 16:37:34 -0800213SyncSocket::onDataValidated(const shared_ptr<const Data>& data,
214 size_t interestNameSize,
215 const OnDataValidated& onValidated)
Yingdi Yu46c9f1a2013-12-18 15:15:46 +0800216{
Yingdi Yu3da10fe2014-02-27 16:37:34 -0800217 if(data->getName().size() > interestNameSize
218 && data->getName().get(interestNameSize).toEscapedString() == "INTRO-CERT")
219 {
Yingdi Yuaed0f3e2014-02-28 14:54:16 -0800220 if(!m_withSecurity)
221 return;
222
Yingdi Yu3da10fe2014-02-27 16:37:34 -0800223 Data rawData;
224 rawData.wireDecode(data->getContent().blockFromValue());
225 IntroCertificate introCert(rawData);
Yingdi Yuaed0f3e2014-02-28 14:54:16 -0800226 dynamic_pointer_cast<SyncValidator>(m_syncValidator)->addParticipant(introCert);
Yingdi Yu3da10fe2014-02-27 16:37:34 -0800227 }
228 else
229 {
230 onValidated(data);
231 }
Yingdi Yu46c9f1a2013-12-18 15:15:46 +0800232}
Yingdi Yu43e71612013-10-30 22:19:31 -0700233
Yingdi Yu3da10fe2014-02-27 16:37:34 -0800234void
235SyncSocket::onDataValidationFailed(const shared_ptr<const Data>& data,
236 const std::string& failureInfo)
Yingdi Yu43e71612013-10-30 22:19:31 -0700237{
Yingdi Yu3da10fe2014-02-27 16:37:34 -0800238 _LOG_DEBUG("data cannot be verified!: " << failureInfo);
Yingdi Yu43e71612013-10-30 22:19:31 -0700239}
240
241}//Sync