blob: 00761dd1cc47d211513f9f4f5b2f9e91b9f17240 [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 +
24 0; // No signed Interest support in mock, otherwise 4 (timestamp, nonce, signed info tlv, signature tlv)
25
26StrategyChoiceManager::StrategyChoiceManager(StrategyChoice& strategyChoice,
27 shared_ptr<AppFace> face)
28 : ManagerBase(face)
29 , 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
62 onValidatedStrategyChoiceRequest(request.shared_from_this());
63}
64
65void
66StrategyChoiceManager::onValidatedStrategyChoiceRequest(const shared_ptr<const Interest>& request)
67{
68 static const Name::Component VERB_SET("set");
69 static const Name::Component VERB_UNSET("unset");
70
71 const Name& command = request->getName();
72
73 ndn::nfd::FibManagementOptions options;
74 if (!extractOptions(*request, options))
75 {
76 sendResponse(command, 400, "Malformed command");
77 return;
78 }
79
80 const Name::Component& verb = command.get(COMMAND_PREFIX.size());
81 ControlResponse response;
82 if (verb == VERB_SET)
83 {
84 setStrategy(options, response);
85 }
86 else if (verb == VERB_UNSET)
87 {
88 unsetStrategy(options, response);
89 }
90 else
91 {
92 NFD_LOG_INFO("command result: unsupported verb: " << verb);
93 setResponse(response, 501, "Unsupported command");
94 }
95 sendResponse(command, response);
96}
97
98bool
99StrategyChoiceManager::extractOptions(const Interest& request,
100 ndn::nfd::FibManagementOptions& extractedOptions)
101{
102 const Name& command = request.getName();
103 const size_t optionCompIndex =
104 COMMAND_PREFIX.size() + 1;
105
106 try
107 {
108 Block rawOptions = request.getName()[optionCompIndex].blockFromValue();
109 extractedOptions.wireDecode(rawOptions);
110 }
111 catch (const ndn::Tlv::Error& e)
112 {
113 NFD_LOG_INFO("Bad command option parse: " << command);
114 return false;
115 }
116
117 NFD_LOG_DEBUG("Options parsed OK");
118 return true;
119}
120
121void
122StrategyChoiceManager::setStrategy(const ndn::nfd::FibManagementOptions& options,
123 ControlResponse& response)
124{
125 const Name& prefix = options.getName();
126 const Name& selectedStrategy = options.getStrategy();
127
128 if (!m_strategyChoice.hasStrategy(selectedStrategy))
129 {
130 NFD_LOG_INFO("strategy-choice result: FAIL reason: unknown-strategy: "
131 << options.getStrategy());
132 setResponse(response, 504, "Unsupported strategy");
133 return;
134 }
135
136 if (m_strategyChoice.insert(prefix, selectedStrategy))
137 {
138 setResponse(response, 200, "Success", options.wireEncode());
139 }
140 else
141 {
142 setResponse(response, 405, "Strategy not installed");
143 }
144}
145
146void
147StrategyChoiceManager::unsetStrategy(const ndn::nfd::FibManagementOptions& options,
148 ControlResponse& response)
149{
150 static const Name ROOT_PREFIX;
151
152 const Name& prefix = options.getName();
153 if (prefix == ROOT_PREFIX)
154 {
155 NFD_LOG_INFO("strategy-choice result: FAIL reason: unknown-prefix: "
156 << options.getName());
157 setResponse(response, 403, "Cannot unset root prefix strategy");
158 return;
159 }
160
161 m_strategyChoice.erase(prefix);
162 setResponse(response, 200, "Success", options.wireEncode());
163}
164
165
166
167} // namespace nfd
168
169