blob: 06adae05b13b66f2750c42a3b550e74820cc0c83 [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
Zhenkai Zhu0d8f5d52012-12-30 12:54:07 -080014CcnxTunnel::~CcnxTunnel()
Zhenkai Zhu0f054122012-12-25 22:22:50 -080015{
16}
17
Zhenkai Zhud4924312012-12-28 11:35:12 -080018void
Zhenkai Zhu0d8f5d52012-12-30 12:54:07 -080019CcnxTunnel::refreshLocalPrefix()
Zhenkai Zhu0f054122012-12-25 22:22:50 -080020{
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 Zhu9bad2bf2012-12-28 15:31:46 -080031CcnxTunnel::sendInterest (const Interest &interest, Closure *closure)
Zhenkai Zhu1ddeb6f2012-12-27 14:04:18 -080032{
Zhenkai Zhu9bad2bf2012-12-28 15:31:46 -080033 string strInterest = interest.name();
34 string tunneledInterest = queryRoutableName(strInterest);
35 Closure *cp = new TunnelClosure(closure, this, strInterest);
Zhenkai Zhu974c5a62012-12-28 14:15:30 -080036 sendInterest(tunneledInterest, cp);
Zhenkai Zhud4924312012-12-28 11:35:12 -080037}
38
Zhenkai Zhu0d8f5d52012-12-30 12:54:07 -080039void
Zhenkai Zhu974c5a62012-12-28 14:15:30 -080040CcnxTunnel::handleTunneledData(const string &name, const Bytes &tunneledData, const Closure::DataCallback &originalDataCallback)
Zhenkai Zhud4924312012-12-28 11:35:12 -080041{
42 ParsedContentObject pco(tunneledData);
43 originalDataCallback(pco.name(), pco.content());
Zhenkai Zhu1ddeb6f2012-12-27 14:04:18 -080044}
45
46int
Zhenkai Zhu974c5a62012-12-28 14:15:30 -080047CcnxTunnel::publishData(const string &name, const unsigned char *buf, size_t len, int freshness)
Zhenkai Zhu0f054122012-12-25 22:22:50 -080048{
Zhenkai Zhud4924312012-12-28 11:35:12 -080049 Bytes content = createContentObject(name, buf, len, freshness);
50 storeContentObject(name, content);
Zhenkai Zhu0d8f5d52012-12-30 12:54:07 -080051
Zhenkai Zhuf1185262012-12-29 17:06:00 -080052 return publishContentObject(name, content, freshness);
53}
Zhenkai Zhu0f054122012-12-25 22:22:50 -080054
Zhenkai Zhuf1185262012-12-29 17:06:00 -080055int
56CcnxTunnel::publishContentObject(const string &name, const Bytes &contentObject, int freshness)
57{
58 string tunneledName = m_localPrefix + name;
59 Bytes tunneledCo = createContentObject(tunneledName, head(contentObject), contentObject.size(), freshness);
Zhenkai Zhu0f054122012-12-25 22:22:50 -080060 return putToCcnd(tunneledCo);
61}
62
63void
Zhenkai Zhud4924312012-12-28 11:35:12 -080064CcnxTunnel::handleTunneledInterest(const string &tunneledInterest)
Zhenkai Zhu0f054122012-12-25 22:22:50 -080065{
66 // The interest must have m_localPrefix as a prefix (component-wise), otherwise ccnd would not deliver it to us
Zhenkai Zhu0d8f5d52012-12-30 12:54:07 -080067 string interest = (m_localPrefix == "/")
Zhenkai Zhu0f054122012-12-25 22:22:50 -080068 ? tunneledInterest
Zhenkai Zhud4924312012-12-28 11:35:12 -080069 : tunneledInterest.substr(m_localPrefix.size());
Zhenkai Zhu0f054122012-12-25 22:22:50 -080070
Zhenkai Zhu0d8f5d52012-12-30 12:54:07 -080071 ReadLock(m_ritLock);
72
Zhenkai Zhu0f054122012-12-25 22:22:50 -080073 // 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)
74 for (RitIter it = m_rit.begin(); it != m_rit.end(); it++)
75 {
76 // evoke callback for any prefix that is the prefix of the interest
Zhenkai Zhud4924312012-12-28 11:35:12 -080077 if (isPrefix(it->first, interest))
Zhenkai Zhu0f054122012-12-25 22:22:50 -080078 {
Zhenkai Zhud4924312012-12-28 11:35:12 -080079 (it->second)(interest);
Zhenkai Zhu0f054122012-12-25 22:22:50 -080080 }
81 }
82}
83
84bool
Zhenkai Zhud4924312012-12-28 11:35:12 -080085CcnxTunnel::isPrefix(const string &prefix, const string &name)
Zhenkai Zhu0f054122012-12-25 22:22:50 -080086{
Zhenkai Zhu0d8f5d52012-12-30 12:54:07 -080087 // prefix is literally prefix of name
Zhenkai Zhu0f054122012-12-25 22:22:50 -080088 if (name.find(prefix) == 0)
89 {
90 // name and prefix are exactly the same, or the next character in name
91 // is '/'; in both case, prefix is the ccnx prefix of name (component-wise)
92 if (name.size() == prefix.size() || name.at(prefix.size()) == '/')
93 {
94 return true;
95 }
96 }
97 return false;
98}
99
Zhenkai Zhu0d8f5d52012-12-30 12:54:07 -0800100int
Zhenkai Zhu0f054122012-12-25 22:22:50 -0800101CcnxTunnel::setInterestFilter(const string &prefix, const InterestCallback &interestCallback)
102{
103 WriteLock(m_ritLock);
Zhenkai Zhud4924312012-12-28 11:35:12 -0800104 // make sure copy constructor for boost::function works properly
105 m_rit.insert(make_pair(prefix, interestCallback));
Zhenkai Zhu0f054122012-12-25 22:22:50 -0800106 return 0;
107}
108
Zhenkai Zhu0d8f5d52012-12-30 12:54:07 -0800109void
Zhenkai Zhu0f054122012-12-25 22:22:50 -0800110CcnxTunnel::clearInterestFilter(const string &prefix)
111{
112 WriteLock(m_ritLock);
113 // remove all
114 m_rit.erase(prefix);
115}
116
Zhenkai Zhu974c5a62012-12-28 14:15:30 -0800117TunnelClosure::TunnelClosure(int retry, const DataCallback &dataCallback, const TimeoutCallback &timeoutCallback, CcnxTunnel *tunnel, const string &originalInterest)
118 : Closure(retry, dataCallback, timeoutCallback)
Zhenkai Zhud4924312012-12-28 11:35:12 -0800119 , m_tunnel(tunnel)
120 , m_originalInterest(originalInterest)
121{
Zhenkai Zhu0f054122012-12-25 22:22:50 -0800122}
123
Zhenkai Zhu974c5a62012-12-28 14:15:30 -0800124TunnelClosure::TunnelClosure(const Closure *closure, CcnxTunnel *tunnel, const string &originalInterest)
125 : Closure(*closure)
126 , m_tunnel(tunnel)
127{
128}
129
Zhenkai Zhu0d8f5d52012-12-30 12:54:07 -0800130void
Zhenkai Zhu974c5a62012-12-28 14:15:30 -0800131TunnelClosure::runDataCallback(const string &name, const Bytes &content)
Zhenkai Zhud4924312012-12-28 11:35:12 -0800132{
133 if (m_tunnel != NULL)
134 {
135 m_tunnel->handleTunneledData(name, content, (*m_dataCallback));
136 }
137}
138
Zhenkai Zhu974c5a62012-12-28 14:15:30 -0800139Closure::TimeoutCallbackReturnValue
140TunnelClosure::runTimeoutCallback(const string &interest)
Zhenkai Zhud4924312012-12-28 11:35:12 -0800141{
Zhenkai Zhu974c5a62012-12-28 14:15:30 -0800142 return Closure::runTimeoutCallback(m_originalInterest);
Zhenkai Zhud4924312012-12-28 11:35:12 -0800143}
144
145} // Ccnx