blob: ca015deda93ebb895f0be8c77cc1bcd1640322c0 [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 std;
25using namespace ndn;
Yingdi Yu46c9f1a2013-12-18 15:15:46 +080026
27INIT_LOGGER ("SyncSocket");
Yingdi Yu43e71612013-10-30 22:19:31 -070028
29namespace Sync {
30
Alexander Afanasyev531803b2014-02-05 15:57:35 -080031using ndn::shared_ptr;
32
Yingdi Yud4ef5d32014-03-01 02:02:01 -080033static const uint8_t ROUTING_PREFIX_SEPARATOR[2] = {0xF0, 0x2E};
34
35const Name SyncSocket::EMPTY_NAME = Name();
36
Yingdi Yu0eee6002014-02-11 15:54:17 -080037SyncSocket::SyncSocket (const Name& syncPrefix,
Yingdi Yud4ef5d32014-03-01 02:02:01 -080038 const Name& dataPrefix,
Yingdi Yu3da10fe2014-02-27 16:37:34 -080039 uint64_t dataSession,
Yingdi Yud4ef5d32014-03-01 02:02:01 -080040 bool withRoutingPrefix,
41 const Name& routingPrefix,
Yingdi Yuaed0f3e2014-02-28 14:54:16 -080042 shared_ptr<Face> face,
Yingdi Yu3da10fe2014-02-27 16:37:34 -080043 const IdentityCertificate& myCertificate,
44 shared_ptr<SecRuleRelative> dataRule,
Yingdi Yu43e71612013-10-30 22:19:31 -070045 NewDataCallback dataCallback,
46 RemoveCallback rmCallback )
Yingdi Yu3da10fe2014-02-27 16:37:34 -080047 : m_dataPrefix(dataPrefix)
48 , m_dataSession(dataSession)
Yingdi Yud4ef5d32014-03-01 02:02:01 -080049 , m_withRoutingPrefix(false)
Yingdi Yu3da10fe2014-02-27 16:37:34 -080050 , m_newDataCallback(dataCallback)
51 , m_myCertificate(myCertificate)
Yingdi Yu6e235db2013-12-27 08:40:53 +080052 , m_face(face)
Yingdi Yu51c80252014-02-10 19:32:05 -080053 , m_ioService(face->ioService())
Yingdi Yuaed0f3e2014-02-28 14:54:16 -080054{
Yingdi Yud4ef5d32014-03-01 02:02:01 -080055 if(withRoutingPrefix && !routingPrefix.isPrefixOf(m_dataPrefix))
56 {
57 m_withRoutingPrefix = true;
58 m_routableDataPrefix.append(routingPrefix).append(ROUTING_PREFIX_SEPARATOR, 2).append(m_dataPrefix);
59 }
60
61
Yingdi Yuaed0f3e2014-02-28 14:54:16 -080062 if(static_cast<bool>(dataRule))
63 {
64 m_withSecurity = true;
65 m_syncValidator = shared_ptr<Validator>(new SyncValidator(syncPrefix,
66 m_myCertificate,
67 m_face,
68 bind(&SyncSocket::publishData, this, _1, _2, _3, true),
69 dataRule));
70 }
71 else
72 {
73 m_withSecurity = false;
74 m_syncValidator = shared_ptr<Validator>(new ValidatorNull());
75 }
76
77
78 m_syncLogic = shared_ptr<SyncLogic>(new SyncLogic(syncPrefix,
79 myCertificate,
80 m_syncValidator,
81 m_face,
82 bind(&SyncSocket::passCallback, this, _1),
83 rmCallback));
84}
Yingdi Yu43e71612013-10-30 22:19:31 -070085
86SyncSocket::~SyncSocket()
Yingdi Yu479e1172013-11-06 16:36:19 -080087{
Yingdi Yu46c9f1a2013-12-18 15:15:46 +080088}
89
Yingdi Yu3da10fe2014-02-27 16:37:34 -080090void
91SyncSocket::publishData(const uint8_t* buf, size_t len, int freshness, bool isCert)
Yingdi Yu43e71612013-10-30 22:19:31 -070092{
Yingdi Yu51c80252014-02-10 19:32:05 -080093 shared_ptr<Data> data = make_shared<Data>();
94 data->setContent(reinterpret_cast<const uint8_t*>(buf), len);
95 data->setFreshnessPeriod(1000*freshness);
96
Yingdi Yu3da10fe2014-02-27 16:37:34 -080097 m_ioService->post(bind(&SyncSocket::publishDataInternal, this,
Yingdi Yud4ef5d32014-03-01 02:02:01 -080098 data, isCert));
Yingdi Yu51c80252014-02-10 19:32:05 -080099}
100
101void
Yingdi Yud4ef5d32014-03-01 02:02:01 -0800102SyncSocket::publishDataInternal(shared_ptr<Data> data, bool isCert)
Yingdi Yu51c80252014-02-10 19:32:05 -0800103{
Yingdi Yud4ef5d32014-03-01 02:02:01 -0800104 Name dataPrefix = (m_withRoutingPrefix ? m_routableDataPrefix : m_dataPrefix);
105
106 uint64_t sequence = getNextSeq();
107
108 Name dataName;
109 dataName.append(m_dataPrefix)
110 .append(boost::lexical_cast<string>(m_dataSession))
111 .append(boost::lexical_cast<string>(sequence));
Yingdi Yu3da10fe2014-02-27 16:37:34 -0800112 if(isCert)
113 dataName.append("INTRO-CERT");
Yingdi Yu51c80252014-02-10 19:32:05 -0800114 data->setName(dataName);
Yingdi Yu3da10fe2014-02-27 16:37:34 -0800115 m_keyChain.sign(*data, m_myCertificate.getName());
Yingdi Yu46c9f1a2013-12-18 15:15:46 +0800116
Yingdi Yud4ef5d32014-03-01 02:02:01 -0800117 if(m_withRoutingPrefix)
118 {
119 Name wrappedName;
120 wrappedName.append(m_routableDataPrefix)
121 .append(boost::lexical_cast<string>(m_dataSession))
122 .append(boost::lexical_cast<string>(sequence));
Yingdi Yu51c80252014-02-10 19:32:05 -0800123
Yingdi Yud4ef5d32014-03-01 02:02:01 -0800124 Data wrappedData(wrappedName);
125 wrappedData.setContent(data->wireEncode());
126 m_keyChain.sign(wrappedData, m_myCertificate.getName());
127
128 m_face->put(wrappedData);
129 }
130 else
131 {
132 m_face->put(*data);
133 }
134
135 SeqNo s(m_dataSession, sequence + 1);
136 m_sequenceLog[dataPrefix] = s;
137 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 -0700138}
139
140void
Yingdi Yud4ef5d32014-03-01 02:02:01 -0800141SyncSocket::fetchData(const Name& prefix, const SeqNo& seq, const OnDataValidated& dataCallback, int retry)
Yingdi Yu43e71612013-10-30 22:19:31 -0700142{
Yingdi Yu6d638f02014-01-24 11:01:21 -0800143 Name interestName = prefix;
Yingdi Yu280bb962014-01-30 09:52:43 -0800144 interestName.append(boost::lexical_cast<string>(seq.getSession())).append(boost::lexical_cast<string>(seq.getSeq()));
Yingdi Yu6d638f02014-01-24 11:01:21 -0800145
Yingdi Yu6d638f02014-01-24 11:01:21 -0800146 ndn::Interest interest(interestName);
Yingdi Yu280bb962014-01-30 09:52:43 -0800147 interest.setMustBeFresh(true);
Yingdi Yu3da10fe2014-02-27 16:37:34 -0800148
Yingdi Yud4ef5d32014-03-01 02:02:01 -0800149 m_face->expressInterest(interest,
150 bind(&SyncSocket::onData, this, _1, _2, dataCallback),
151 bind(&SyncSocket::onDataTimeout, this, _1, retry, dataCallback));
152
153}
154
155void
156SyncSocket::onData(const ndn::Interest& interest, Data& data, const OnDataValidated& dataCallback)
157{
158 bool encaped = false;
159
160 Name interestName = interest.getName();
161 Name::const_iterator it = interestName.begin();
162 Name::const_iterator end = interestName.end();
163
164 size_t offset = interestName.size();
165 for(; it != end; it++)
166 {
167 offset--;
168 if(it->toEscapedString() == "%F0.")
169 {
170 encaped = true;
171 break;
172 }
173 }
174
175 if(!encaped)
176 offset = interestName.size();
177
178 const OnDataValidated& onValidated = bind(&SyncSocket::onDataValidated, this, _1, offset, dataCallback);
Yingdi Yu3da10fe2014-02-27 16:37:34 -0800179 const OnDataValidationFailed& onValidationFailed = bind(&SyncSocket::onDataValidationFailed, this, _1, _2);
180
Yingdi Yud4ef5d32014-03-01 02:02:01 -0800181 if(encaped)
182 {
183 shared_ptr<Data> innerData = make_shared<Data>();
184 innerData->wireDecode(data.getContent().blockFromValue());
185 m_syncValidator->validate(*innerData, onValidated, onValidationFailed);
186 }
187 else
188 m_syncValidator->validate(data, onValidated, onValidationFailed);
Yingdi Yu43e71612013-10-30 22:19:31 -0700189}
190
191void
Yingdi Yud4ef5d32014-03-01 02:02:01 -0800192SyncSocket::onDataTimeout(const ndn::Interest& interest, int retry, const OnDataValidated& dataCallback)
Yingdi Yu43e71612013-10-30 22:19:31 -0700193{
194 if(retry > 0)
195 {
Yingdi Yu51c80252014-02-10 19:32:05 -0800196 m_face->expressInterest(interest,
Yingdi Yu6d638f02014-01-24 11:01:21 -0800197 bind(&SyncSocket::onData,
Yingdi Yu46c9f1a2013-12-18 15:15:46 +0800198 this,
199 _1,
200 _2,
Yingdi Yud4ef5d32014-03-01 02:02:01 -0800201 dataCallback),
Yingdi Yu6d638f02014-01-24 11:01:21 -0800202 bind(&SyncSocket::onDataTimeout,
Yingdi Yu46c9f1a2013-12-18 15:15:46 +0800203 this,
204 _1,
205 retry - 1,
Yingdi Yud4ef5d32014-03-01 02:02:01 -0800206 dataCallback));
Yingdi Yu46c9f1a2013-12-18 15:15:46 +0800207
Yingdi Yu43e71612013-10-30 22:19:31 -0700208 }
Yingdi Yu46c9f1a2013-12-18 15:15:46 +0800209 else
Yingdi Yu6d638f02014-01-24 11:01:21 -0800210 _LOG_DEBUG("interest eventually time out!");
Yingdi Yu43e71612013-10-30 22:19:31 -0700211}
212
213void
Yingdi Yu3da10fe2014-02-27 16:37:34 -0800214SyncSocket::onDataValidated(const shared_ptr<const Data>& data,
215 size_t interestNameSize,
216 const OnDataValidated& onValidated)
Yingdi Yu46c9f1a2013-12-18 15:15:46 +0800217{
Yingdi Yu3da10fe2014-02-27 16:37:34 -0800218 if(data->getName().size() > interestNameSize
219 && data->getName().get(interestNameSize).toEscapedString() == "INTRO-CERT")
220 {
Yingdi Yuaed0f3e2014-02-28 14:54:16 -0800221 if(!m_withSecurity)
222 return;
223
Yingdi Yu3da10fe2014-02-27 16:37:34 -0800224 Data rawData;
225 rawData.wireDecode(data->getContent().blockFromValue());
226 IntroCertificate introCert(rawData);
Yingdi Yuaed0f3e2014-02-28 14:54:16 -0800227 dynamic_pointer_cast<SyncValidator>(m_syncValidator)->addParticipant(introCert);
Yingdi Yu3da10fe2014-02-27 16:37:34 -0800228 }
229 else
230 {
231 onValidated(data);
232 }
Yingdi Yu46c9f1a2013-12-18 15:15:46 +0800233}
Yingdi Yu43e71612013-10-30 22:19:31 -0700234
Yingdi Yu3da10fe2014-02-27 16:37:34 -0800235void
236SyncSocket::onDataValidationFailed(const shared_ptr<const Data>& data,
237 const std::string& failureInfo)
Yingdi Yu43e71612013-10-30 22:19:31 -0700238{
Yingdi Yu3da10fe2014-02-27 16:37:34 -0800239 _LOG_DEBUG("data cannot be verified!: " << failureInfo);
Yingdi Yu43e71612013-10-30 22:19:31 -0700240}
241
242}//Sync