blob: 0984d26467cb108568429bcea76a7d5ea3fedbf3 [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
Alexander Afanasyev1dd37ed2013-08-14 18:08:09 -070022#include "ndnx-tunnel.h"
23#include "ndnx-pco.h"
Zhenkai Zhu0f054122012-12-25 22:22:50 -080024
Alexander Afanasyev1dd37ed2013-08-14 18:08:09 -070025namespace Ndnx
Zhenkai Zhu0f054122012-12-25 22:22:50 -080026{
27
Alexander Afanasyev1dd37ed2013-08-14 18:08:09 -070028NdnxTunnel::NdnxTunnel()
29 : NdnxWrapper()
Alexander Afanasyev66f4c492013-01-20 23:32:50 -080030 , 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
Alexander Afanasyev1dd37ed2013-08-14 18:08:09 -070035NdnxTunnel::~NdnxTunnel()
Zhenkai Zhu0f054122012-12-25 22:22:50 -080036{
37}
38
Zhenkai Zhud4924312012-12-28 11:35:12 -080039void
Alexander Afanasyev1dd37ed2013-08-14 18:08:09 -070040NdnxTunnel::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 {
Alexander Afanasyev1dd37ed2013-08-14 18:08:09 -070045 NdnxWrapper::clearInterestFilter(m_localPrefix);
46 NdnxWrapper::setInterestFilter(newPrefix, bind(&NdnxTunnel::handleTunneledInterest, this, _1));
Zhenkai Zhu0f054122012-12-25 22:22:50 -080047 m_localPrefix = newPrefix;
48 }
49}
50
51int
Alexander Afanasyev1dd37ed2013-08-14 18:08:09 -070052NdnxTunnel::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
Alexander Afanasyev1dd37ed2013-08-14 18:08:09 -070056 NdnxWrapper::sendInterest(tunneledInterest,
Alexander Afanasyevd6c2a902013-01-19 21:24:30 -080057 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
Alexander Afanasyev1dd37ed2013-08-14 18:08:09 -070064NdnxTunnel::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
Alexander Afanasyev1dd37ed2013-08-14 18:08:09 -070071NdnxTunnel::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
Alexander Afanasyev1dd37ed2013-08-14 18:08:09 -070080NdnxTunnel::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);
Alexander Afanasyev1dd37ed2013-08-14 18:08:09 -070084 return putToNdnd(tunneledCo);
Zhenkai Zhu0f054122012-12-25 22:22:50 -080085}
86
87void
Alexander Afanasyev1dd37ed2013-08-14 18:08:09 -070088NdnxTunnel::handleTunneledInterest(const Name &tunneledInterest)
Zhenkai Zhu0f054122012-12-25 22:22:50 -080089{
Alexander Afanasyev1dd37ed2013-08-14 18:08:09 -070090 // The interest must have m_localPrefix as a prefix (component-wise), otherwise ndnd 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
Alexander Afanasyev1dd37ed2013-08-14 18:08:09 -0700107NdnxTunnel::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
Alexander Afanasyev1dd37ed2013-08-14 18:08:09 -0700127NdnxTunnel::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
Alexander Afanasyev1dd37ed2013-08-14 18:08:09 -0700136NdnxTunnel::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 Afanasyev1dd37ed2013-08-14 18:08:09 -0700143TunnelClosure::TunnelClosure(const DataCallback &dataCallback, NdnxTunnel &tunnel,
Alexander Afanasyevd6c2a902013-01-19 21:24:30 -0800144 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 Afanasyev1dd37ed2013-08-14 18:08:09 -0700151TunnelClosure::TunnelClosure(const Closure &closure, NdnxTunnel &tunnel, const Name &originalInterest)
Alexander Afanasyevd6c2a902013-01-19 21:24:30 -0800152 : 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
Alexander Afanasyev1dd37ed2013-08-14 18:08:09 -0700175} // Ndnx