blob: cd4dc5bc640794feda19d93395c27c1593a6ba6e [file] [log] [blame]
Steve DiBenedetto5330e0d2014-03-05 21:52:51 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (C) 2014 Named Data Networking Project
4 * See COPYING for copyright and distribution information.
5 */
6
7#include "strategy-choice-manager.hpp"
8#include "table/strategy-choice.hpp"
9#include "mgmt/app-face.hpp"
10
11namespace nfd {
12
13NFD_LOG_INIT("StrategyChoiceManager");
14
15const Name StrategyChoiceManager::COMMAND_PREFIX = "/localhost/nfd/strategy-choice";
16
17const size_t StrategyChoiceManager::COMMAND_UNSIGNED_NCOMPS =
18 StrategyChoiceManager::COMMAND_PREFIX.size() +
19 1 + // verb
20 1; // verb options
21
22const size_t StrategyChoiceManager::COMMAND_SIGNED_NCOMPS =
23 StrategyChoiceManager::COMMAND_UNSIGNED_NCOMPS +
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070024 4; // (timestamp, nonce, signed info tlv, signature tlv)
Steve DiBenedetto5330e0d2014-03-05 21:52:51 -070025
26StrategyChoiceManager::StrategyChoiceManager(StrategyChoice& strategyChoice,
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070027 shared_ptr<InternalFace> face)
28 : ManagerBase(face, STRATEGY_CHOICE_PRIVILEGE)
Steve DiBenedetto5330e0d2014-03-05 21:52:51 -070029 , m_strategyChoice(strategyChoice)
30{
31 face->setInterestFilter("/localhost/nfd/strategy-choice",
32 bind(&StrategyChoiceManager::onStrategyChoiceRequest, this, _2));
33}
34
35StrategyChoiceManager::~StrategyChoiceManager()
36{
37
38}
39
40void
41StrategyChoiceManager::onStrategyChoiceRequest(const Interest& request)
42{
43 const Name& command = request.getName();
44 const size_t commandNComps = command.size();
45
46 if (COMMAND_UNSIGNED_NCOMPS <= commandNComps &&
47 commandNComps < COMMAND_SIGNED_NCOMPS)
48 {
49 NFD_LOG_INFO("command result: unsigned verb: " << command);
50 sendResponse(command, 401, "Signature required");
51
52 return;
53 }
54 else if (commandNComps < COMMAND_SIGNED_NCOMPS ||
55 !COMMAND_PREFIX.isPrefixOf(command))
56 {
57 NFD_LOG_INFO("command result: malformed");
58 sendResponse(command, 400, "Malformed command");
59 return;
60 }
61
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070062 validate(request,
63 bind(&StrategyChoiceManager::onValidatedStrategyChoiceRequest, this, _1),
64 bind(&ManagerBase::onCommandValidationFailed, this, _1, _2));
Steve DiBenedetto5330e0d2014-03-05 21:52:51 -070065}
66
67void
68StrategyChoiceManager::onValidatedStrategyChoiceRequest(const shared_ptr<const Interest>& request)
69{
70 static const Name::Component VERB_SET("set");
71 static const Name::Component VERB_UNSET("unset");
72
73 const Name& command = request->getName();
74
Steve DiBenedetto1d75f542014-03-15 19:21:44 -060075 ndn::nfd::StrategyChoiceOptions options;
Steve DiBenedetto5330e0d2014-03-05 21:52:51 -070076 if (!extractOptions(*request, options))
77 {
78 sendResponse(command, 400, "Malformed command");
79 return;
80 }
81
82 const Name::Component& verb = command.get(COMMAND_PREFIX.size());
83 ControlResponse response;
84 if (verb == VERB_SET)
85 {
86 setStrategy(options, response);
87 }
88 else if (verb == VERB_UNSET)
89 {
90 unsetStrategy(options, response);
91 }
92 else
93 {
94 NFD_LOG_INFO("command result: unsupported verb: " << verb);
95 setResponse(response, 501, "Unsupported command");
96 }
97 sendResponse(command, response);
98}
99
100bool
101StrategyChoiceManager::extractOptions(const Interest& request,
Steve DiBenedetto1d75f542014-03-15 19:21:44 -0600102 ndn::nfd::StrategyChoiceOptions& extractedOptions)
Steve DiBenedetto5330e0d2014-03-05 21:52:51 -0700103{
104 const Name& command = request.getName();
105 const size_t optionCompIndex =
106 COMMAND_PREFIX.size() + 1;
107
108 try
109 {
110 Block rawOptions = request.getName()[optionCompIndex].blockFromValue();
111 extractedOptions.wireDecode(rawOptions);
112 }
113 catch (const ndn::Tlv::Error& e)
114 {
115 NFD_LOG_INFO("Bad command option parse: " << command);
116 return false;
117 }
118
119 NFD_LOG_DEBUG("Options parsed OK");
120 return true;
121}
122
123void
Steve DiBenedetto1d75f542014-03-15 19:21:44 -0600124StrategyChoiceManager::setStrategy(const ndn::nfd::StrategyChoiceOptions& options,
Steve DiBenedetto5330e0d2014-03-05 21:52:51 -0700125 ControlResponse& response)
126{
127 const Name& prefix = options.getName();
128 const Name& selectedStrategy = options.getStrategy();
129
130 if (!m_strategyChoice.hasStrategy(selectedStrategy))
131 {
132 NFD_LOG_INFO("strategy-choice result: FAIL reason: unknown-strategy: "
133 << options.getStrategy());
134 setResponse(response, 504, "Unsupported strategy");
135 return;
136 }
137
138 if (m_strategyChoice.insert(prefix, selectedStrategy))
139 {
140 setResponse(response, 200, "Success", options.wireEncode());
141 }
142 else
143 {
144 setResponse(response, 405, "Strategy not installed");
145 }
146}
147
148void
Steve DiBenedetto1d75f542014-03-15 19:21:44 -0600149StrategyChoiceManager::unsetStrategy(const ndn::nfd::StrategyChoiceOptions& options,
Steve DiBenedetto5330e0d2014-03-05 21:52:51 -0700150 ControlResponse& response)
151{
152 static const Name ROOT_PREFIX;
153
154 const Name& prefix = options.getName();
155 if (prefix == ROOT_PREFIX)
156 {
157 NFD_LOG_INFO("strategy-choice result: FAIL reason: unknown-prefix: "
158 << options.getName());
159 setResponse(response, 403, "Cannot unset root prefix strategy");
160 return;
161 }
162
163 m_strategyChoice.erase(prefix);
164 setResponse(response, 200, "Success", options.wireEncode());
165}
166
167
168
169} // namespace nfd
170
171