blob: 467f7a171067e828c228ef473b79cc14db18e4a9 [file] [log] [blame]
Zhenkai Zhu0f054122012-12-25 22:22:50 -08001#include "ccnx-tunnel.h"
Zhenkai Zhud4924312012-12-28 11:35:12 -08002#include "ccnx-pco.h"
Zhenkai Zhu0f054122012-12-25 22:22:50 -08003
4namespace Ccnx
5{
6
7CcnxTunnel::CcnxTunnel()
8 : CcnxWrapper()
9 , m_localPrefix("/")
10{
11 refreshLocalPrefix();
12}
13
14CcnxTunnel::~CcnxTunnel()
15{
16}
17
Zhenkai Zhud4924312012-12-28 11:35:12 -080018void
Zhenkai Zhu0f054122012-12-25 22:22:50 -080019CcnxTunnel::refreshLocalPrefix()
20{
21 string newPrefix = getLocalPrefix();
22 if (!newPrefix.empty() && m_localPrefix != newPrefix)
23 {
24 CcnxWrapper::clearInterestFilter(m_localPrefix);
25 CcnxWrapper::setInterestFilter(newPrefix, bind(&CcnxTunnel::handleTunneledInterest, this, _1));
26 m_localPrefix = newPrefix;
27 }
28}
29
30int
Zhenkai Zhu974c5a62012-12-28 14:15:30 -080031CcnxTunnel::sendInterest (const std::string &interest, Closure *closure)
Zhenkai Zhu1ddeb6f2012-12-27 14:04:18 -080032{
33 string tunneledInterest = queryRoutableName(interest);
Zhenkai Zhu974c5a62012-12-28 14:15:30 -080034 Closure *cp = new TunnelClosure(closure, this, interest);
35 sendInterest(tunneledInterest, cp);
Zhenkai Zhud4924312012-12-28 11:35:12 -080036}
37
38void
Zhenkai Zhu974c5a62012-12-28 14:15:30 -080039CcnxTunnel::handleTunneledData(const string &name, const Bytes &tunneledData, const Closure::DataCallback &originalDataCallback)
Zhenkai Zhud4924312012-12-28 11:35:12 -080040{
41 ParsedContentObject pco(tunneledData);
42 originalDataCallback(pco.name(), pco.content());
Zhenkai Zhu1ddeb6f2012-12-27 14:04:18 -080043}
44
45int
Zhenkai Zhu974c5a62012-12-28 14:15:30 -080046CcnxTunnel::publishData(const string &name, const unsigned char *buf, size_t len, int freshness)
Zhenkai Zhu0f054122012-12-25 22:22:50 -080047{
Zhenkai Zhud4924312012-12-28 11:35:12 -080048 Bytes content = createContentObject(name, buf, len, freshness);
49 storeContentObject(name, content);
Zhenkai Zhu0f054122012-12-25 22:22:50 -080050
Zhenkai Zhu1ddeb6f2012-12-27 14:04:18 -080051 string tunneledName = m_localPrefix + name;
Zhenkai Zhu974c5a62012-12-28 14:15:30 -080052 Bytes tunneledCo = createContentObject(tunneledName, head(content), content.size(), freshness);
Zhenkai Zhu0f054122012-12-25 22:22:50 -080053
54 return putToCcnd(tunneledCo);
55}
56
57void
Zhenkai Zhud4924312012-12-28 11:35:12 -080058CcnxTunnel::handleTunneledInterest(const string &tunneledInterest)
Zhenkai Zhu0f054122012-12-25 22:22:50 -080059{
60 // The interest must have m_localPrefix as a prefix (component-wise), otherwise ccnd would not deliver it to us
61 string interest = (m_localPrefix == "/")
62 ? tunneledInterest
Zhenkai Zhud4924312012-12-28 11:35:12 -080063 : tunneledInterest.substr(m_localPrefix.size());
Zhenkai Zhu0f054122012-12-25 22:22:50 -080064
65 ReadLock(m_ritLock);
66
67 // 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)
68 for (RitIter it = m_rit.begin(); it != m_rit.end(); it++)
69 {
70 // evoke callback for any prefix that is the prefix of the interest
Zhenkai Zhud4924312012-12-28 11:35:12 -080071 if (isPrefix(it->first, interest))
Zhenkai Zhu0f054122012-12-25 22:22:50 -080072 {
Zhenkai Zhud4924312012-12-28 11:35:12 -080073 (it->second)(interest);
Zhenkai Zhu0f054122012-12-25 22:22:50 -080074 }
75 }
76}
77
78bool
Zhenkai Zhud4924312012-12-28 11:35:12 -080079CcnxTunnel::isPrefix(const string &prefix, const string &name)
Zhenkai Zhu0f054122012-12-25 22:22:50 -080080{
81 // prefix is literally prefix of name
82 if (name.find(prefix) == 0)
83 {
84 // name and prefix are exactly the same, or the next character in name
85 // is '/'; in both case, prefix is the ccnx prefix of name (component-wise)
86 if (name.size() == prefix.size() || name.at(prefix.size()) == '/')
87 {
88 return true;
89 }
90 }
91 return false;
92}
93
94int
95CcnxTunnel::setInterestFilter(const string &prefix, const InterestCallback &interestCallback)
96{
97 WriteLock(m_ritLock);
Zhenkai Zhud4924312012-12-28 11:35:12 -080098 // make sure copy constructor for boost::function works properly
99 m_rit.insert(make_pair(prefix, interestCallback));
Zhenkai Zhu0f054122012-12-25 22:22:50 -0800100 return 0;
101}
102
103void
104CcnxTunnel::clearInterestFilter(const string &prefix)
105{
106 WriteLock(m_ritLock);
107 // remove all
108 m_rit.erase(prefix);
109}
110
Zhenkai Zhu974c5a62012-12-28 14:15:30 -0800111TunnelClosure::TunnelClosure(int retry, const DataCallback &dataCallback, const TimeoutCallback &timeoutCallback, CcnxTunnel *tunnel, const string &originalInterest)
112 : Closure(retry, dataCallback, timeoutCallback)
Zhenkai Zhud4924312012-12-28 11:35:12 -0800113 , m_tunnel(tunnel)
114 , m_originalInterest(originalInterest)
115{
Zhenkai Zhu0f054122012-12-25 22:22:50 -0800116}
117
Zhenkai Zhu974c5a62012-12-28 14:15:30 -0800118TunnelClosure::TunnelClosure(const Closure *closure, CcnxTunnel *tunnel, const string &originalInterest)
119 : Closure(*closure)
120 , m_tunnel(tunnel)
121{
122}
123
Zhenkai Zhud4924312012-12-28 11:35:12 -0800124void
Zhenkai Zhu974c5a62012-12-28 14:15:30 -0800125TunnelClosure::runDataCallback(const string &name, const Bytes &content)
Zhenkai Zhud4924312012-12-28 11:35:12 -0800126{
127 if (m_tunnel != NULL)
128 {
129 m_tunnel->handleTunneledData(name, content, (*m_dataCallback));
130 }
131}
132
Zhenkai Zhu974c5a62012-12-28 14:15:30 -0800133Closure::TimeoutCallbackReturnValue
134TunnelClosure::runTimeoutCallback(const string &interest)
Zhenkai Zhud4924312012-12-28 11:35:12 -0800135{
Zhenkai Zhu974c5a62012-12-28 14:15:30 -0800136 return Closure::runTimeoutCallback(m_originalInterest);
Zhenkai Zhud4924312012-12-28 11:35:12 -0800137}
138
139} // Ccnx