blob: def125a5279df8cf4bf1d9755f5e8673d1f493aa [file] [log] [blame]
Alexander Afanasyevd6c2a902013-01-19 21:24:30 -08001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2013 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: Zhenkai Zhu <zhenkai@cs.ucla.edu>
19 * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
20 */
21
Zhenkai Zhu0f054122012-12-25 22:22:50 -080022#include "ccnx-tunnel.h"
Zhenkai Zhud4924312012-12-28 11:35:12 -080023#include "ccnx-pco.h"
Zhenkai Zhu0f054122012-12-25 22:22:50 -080024
25namespace Ccnx
26{
27
28CcnxTunnel::CcnxTunnel()
Alexander Afanasyev66f4c492013-01-20 23:32:50 -080029 : CcnxWrapper()
30 , m_localPrefix("/")
Zhenkai Zhu0f054122012-12-25 22:22:50 -080031{
Zhenkai Zhu19f81de2013-01-04 22:27:47 -080032 refreshLocalPrefix();
Zhenkai Zhu0f054122012-12-25 22:22:50 -080033}
34
Zhenkai Zhu0d8f5d52012-12-30 12:54:07 -080035CcnxTunnel::~CcnxTunnel()
Zhenkai Zhu0f054122012-12-25 22:22:50 -080036{
37}
38
Zhenkai Zhud4924312012-12-28 11:35:12 -080039void
Zhenkai Zhu0d8f5d52012-12-30 12:54:07 -080040CcnxTunnel::refreshLocalPrefix()
Zhenkai Zhu0f054122012-12-25 22:22:50 -080041{
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -080042 Name newPrefix = getLocalPrefix();
43 if (!newPrefix.toString().empty() && m_localPrefix != newPrefix)
Zhenkai Zhu0f054122012-12-25 22:22:50 -080044 {
45 CcnxWrapper::clearInterestFilter(m_localPrefix);
46 CcnxWrapper::setInterestFilter(newPrefix, bind(&CcnxTunnel::handleTunneledInterest, this, _1));
47 m_localPrefix = newPrefix;
48 }
49}
50
51int
Alexander Afanasyevd6c2a902013-01-19 21:24:30 -080052CcnxTunnel::sendInterest (const Name &interest, const Closure &closure, const Selectors &selectors)
Zhenkai Zhu1ddeb6f2012-12-27 14:04:18 -080053{
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -080054 Name tunneledInterest = queryRoutableName(interest);
Alexander Afanasyevd6c2a902013-01-19 21:24:30 -080055
56 CcnxWrapper::sendInterest(tunneledInterest,
57 TunnelClosure(closure, *this, interest),
58 selectors);
Alexander Afanasyevdcfa9632013-01-07 16:38:19 -080059
60 return 0;
Zhenkai Zhud4924312012-12-28 11:35:12 -080061}
62
Zhenkai Zhu0d8f5d52012-12-30 12:54:07 -080063void
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -080064CcnxTunnel::handleTunneledData(const Name &name, const Bytes &tunneledData, const Closure::DataCallback &originalDataCallback)
Zhenkai Zhud4924312012-12-28 11:35:12 -080065{
66 ParsedContentObject pco(tunneledData);
67 originalDataCallback(pco.name(), pco.content());
Zhenkai Zhu1ddeb6f2012-12-27 14:04:18 -080068}
69
70int
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -080071CcnxTunnel::publishData(const Name &name, const unsigned char *buf, size_t len, int freshness)
Zhenkai Zhu0f054122012-12-25 22:22:50 -080072{
Zhenkai Zhud4924312012-12-28 11:35:12 -080073 Bytes content = createContentObject(name, buf, len, freshness);
74 storeContentObject(name, content);
Zhenkai Zhu0d8f5d52012-12-30 12:54:07 -080075
Zhenkai Zhuf1185262012-12-29 17:06:00 -080076 return publishContentObject(name, content, freshness);
77}
Zhenkai Zhu0f054122012-12-25 22:22:50 -080078
Zhenkai Zhuf1185262012-12-29 17:06:00 -080079int
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -080080CcnxTunnel::publishContentObject(const Name &name, const Bytes &contentObject, int freshness)
Zhenkai Zhuf1185262012-12-29 17:06:00 -080081{
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -080082 Name tunneledName = m_localPrefix + name;
Zhenkai Zhuf1185262012-12-29 17:06:00 -080083 Bytes tunneledCo = createContentObject(tunneledName, head(contentObject), contentObject.size(), freshness);
Zhenkai Zhu0f054122012-12-25 22:22:50 -080084 return putToCcnd(tunneledCo);
85}
86
87void
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -080088CcnxTunnel::handleTunneledInterest(const Name &tunneledInterest)
Zhenkai Zhu0f054122012-12-25 22:22:50 -080089{
90 // The interest must have m_localPrefix as a prefix (component-wise), otherwise ccnd would not deliver it to us
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -080091 Name interest = tunneledInterest.getPartialName(m_localPrefix.size());
Zhenkai Zhu0f054122012-12-25 22:22:50 -080092
Zhenkai Zhu4865bd62013-01-17 12:08:29 -080093 ReadLock lock(m_ritLock);
Zhenkai Zhu0d8f5d52012-12-30 12:54:07 -080094
Zhenkai Zhu0f054122012-12-25 22:22:50 -080095 // This is linear scan, but should be acceptable under the assumption that the caller wouldn't be listening to a lot prefixes (as of now, most app listen to one or two prefixes)
96 for (RitIter it = m_rit.begin(); it != m_rit.end(); it++)
97 {
98 // evoke callback for any prefix that is the prefix of the interest
Zhenkai Zhud4924312012-12-28 11:35:12 -080099 if (isPrefix(it->first, interest))
Zhenkai Zhu0f054122012-12-25 22:22:50 -0800100 {
Zhenkai Zhud4924312012-12-28 11:35:12 -0800101 (it->second)(interest);
Zhenkai Zhu0f054122012-12-25 22:22:50 -0800102 }
103 }
104}
105
106bool
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800107CcnxTunnel::isPrefix(const Name &prefix, const Name &name)
Zhenkai Zhu0f054122012-12-25 22:22:50 -0800108{
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800109 if (prefix.size() > name.size())
Zhenkai Zhu0f054122012-12-25 22:22:50 -0800110 {
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800111 return false;
112 }
113
114 int size = prefix.size();
115 for (int i = 0; i < size; i++)
116 {
117 if (prefix.getCompAsString(i) != name.getCompAsString(i))
Zhenkai Zhu0f054122012-12-25 22:22:50 -0800118 {
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800119 return false;
Zhenkai Zhu0f054122012-12-25 22:22:50 -0800120 }
121 }
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800122
123 return true;
Zhenkai Zhu0f054122012-12-25 22:22:50 -0800124}
125
Zhenkai Zhu0d8f5d52012-12-30 12:54:07 -0800126int
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800127CcnxTunnel::setInterestFilter(const Name &prefix, const InterestCallback &interestCallback)
Zhenkai Zhu0f054122012-12-25 22:22:50 -0800128{
Zhenkai Zhu4865bd62013-01-17 12:08:29 -0800129 WriteLock lock(m_ritLock);
Zhenkai Zhud4924312012-12-28 11:35:12 -0800130 // make sure copy constructor for boost::function works properly
131 m_rit.insert(make_pair(prefix, interestCallback));
Zhenkai Zhu0f054122012-12-25 22:22:50 -0800132 return 0;
133}
134
Zhenkai Zhu0d8f5d52012-12-30 12:54:07 -0800135void
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800136CcnxTunnel::clearInterestFilter(const Name &prefix)
Zhenkai Zhu0f054122012-12-25 22:22:50 -0800137{
Zhenkai Zhu4865bd62013-01-17 12:08:29 -0800138 WriteLock lock(m_ritLock);
Zhenkai Zhu0f054122012-12-25 22:22:50 -0800139 // remove all
140 m_rit.erase(prefix);
141}
142
Alexander Afanasyevd6c2a902013-01-19 21:24:30 -0800143TunnelClosure::TunnelClosure(const DataCallback &dataCallback, CcnxTunnel &tunnel,
144 const Name &originalInterest, const TimeoutCallback &timeoutCallback)
145 : Closure(dataCallback, timeoutCallback)
146 , m_tunnel(tunnel)
147 , m_originalInterest(originalInterest)
Zhenkai Zhud4924312012-12-28 11:35:12 -0800148{
Zhenkai Zhu0f054122012-12-25 22:22:50 -0800149}
150
Alexander Afanasyevd6c2a902013-01-19 21:24:30 -0800151TunnelClosure::TunnelClosure(const Closure &closure, CcnxTunnel &tunnel, const Name &originalInterest)
152 : Closure(closure)
153 , m_tunnel(tunnel)
Zhenkai Zhu974c5a62012-12-28 14:15:30 -0800154{
155}
156
Zhenkai Zhu19f81de2013-01-04 22:27:47 -0800157Closure *
158TunnelClosure::dup() const
159{
Alexander Afanasyevd6c2a902013-01-19 21:24:30 -0800160 return new TunnelClosure (*this);
Zhenkai Zhu19f81de2013-01-04 22:27:47 -0800161}
162
Zhenkai Zhu0d8f5d52012-12-30 12:54:07 -0800163void
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800164TunnelClosure::runDataCallback(const Name &name, const Bytes &content)
Zhenkai Zhud4924312012-12-28 11:35:12 -0800165{
Alexander Afanasyevd6c2a902013-01-19 21:24:30 -0800166 m_tunnel.handleTunneledData(name, content, m_dataCallback);
Zhenkai Zhud4924312012-12-28 11:35:12 -0800167}
168
Zhenkai Zhu974c5a62012-12-28 14:15:30 -0800169Closure::TimeoutCallbackReturnValue
Zhenkai Zhucb2d0dd2013-01-03 14:10:48 -0800170TunnelClosure::runTimeoutCallback(const Name &interest)
Zhenkai Zhud4924312012-12-28 11:35:12 -0800171{
Zhenkai Zhu974c5a62012-12-28 14:15:30 -0800172 return Closure::runTimeoutCallback(m_originalInterest);
Zhenkai Zhud4924312012-12-28 11:35:12 -0800173}
174
175} // Ccnx