blob: 67ca9e0979cc65ca0f8db00896489d82d4e3ddcc [file] [log] [blame]
Andrew Brown2f1fdbf2015-01-21 10:52:29 -08001/*
andrewsbrown7e6b9e82015-03-03 16:11:11 -08002 * jndn-management
3 * Copyright (c) 2015, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU Lesser General Public License,
7 * version 3, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT ANY
10 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
12 * more details.
Andrew Brown2f1fdbf2015-01-21 10:52:29 -080013 */
14package com.intel.jndn.management;
15
Andrew Brownc46c1602015-02-18 10:45:56 -080016import com.intel.jndn.management.types.StatusDataset;
17import com.intel.jndn.management.types.ControlResponse;
18import com.intel.jndn.management.types.FaceStatus;
Andrew Brown63bed362015-02-18 11:28:50 -080019import com.intel.jndn.management.types.FibEntry;
andrewsbrown8a32f302015-03-24 08:42:46 -070020import com.intel.jndn.management.types.ForwarderStatus;
andrewsbrowne8e8e852015-03-09 13:48:31 -070021import com.intel.jndn.management.types.LocalControlHeader;
Andrew Brownc46c1602015-02-18 10:45:56 -080022import com.intel.jndn.management.types.RibEntry;
andrewsbrown39b0fc92015-05-11 13:44:38 -070023import com.intel.jndn.management.types.StrategyChoice;
Andrew Brownbaf21d52015-07-13 10:32:46 -070024import com.intel.jndn.utils.client.SegmentedClient;
25import com.intel.jndn.utils.client.SimpleClient;
Andrew Brown2f1fdbf2015-01-21 10:52:29 -080026import java.io.IOException;
27import java.util.List;
28import net.named_data.jndn.ControlParameters;
29import net.named_data.jndn.Data;
30import net.named_data.jndn.Face;
31import net.named_data.jndn.ForwardingFlags;
32import net.named_data.jndn.Interest;
33import net.named_data.jndn.Name;
34import net.named_data.jndn.encoding.EncodingException;
35import net.named_data.jndn.security.SecurityException;
Andrew Brownc46c1602015-02-18 10:45:56 -080036import java.util.logging.Logger;
Andrew Brownc5dda702015-04-13 09:36:04 -070037import net.named_data.jndn.KeyLocator;
Andrew Brown2f1fdbf2015-01-21 10:52:29 -080038
39/**
40 * Helper class for interacting with an NDN forwarder daemon; see
andrewsbrown9a6d7ba2015-03-24 09:53:29 -070041 * <a href="http://redmine.named-data.net/projects/nfd/wiki/Management">http://redmine.named-data.net/projects/nfd/wiki/Management</a>
42 * for explanations of the various protocols used.
Andrew Brown2f1fdbf2015-01-21 10:52:29 -080043 *
44 * @author Andrew Brown <andrew.brown@intel.com>
45 */
46public class NFD {
47
Andrew Brown211d2b62015-02-18 11:12:02 -080048 public final static long DEFAULT_TIMEOUT = 2000;
andrewsbrown43b96302015-03-17 21:51:43 +010049 public final static int OK_STATUS = 200;
Andrew Brown211d2b62015-02-18 11:12:02 -080050 static private final Logger logger = Logger.getLogger(NFD.class.getName());
Andrew Brown2f1fdbf2015-01-21 10:52:29 -080051
Andrew Brown211d2b62015-02-18 11:12:02 -080052 /**
53 * Ping a forwarder on an existing face to verify that the forwarder is
54 * working and responding to requests; this version sends a discovery packet
55 * to /localhost/nfd which should always respond if the requestor is on the
56 * same machine as the NDN forwarding daemon.
57 *
andrewsbrown8a32f302015-03-24 08:42:46 -070058 * @param face only a localhost Face
Andrew Brown211d2b62015-02-18 11:12:02 -080059 * @return true if successful, false otherwise
60 */
61 public static boolean pingLocal(Face face) {
62 return ping(face, new Name("/localhost/nfd"));
63 }
Andrew Brown2f1fdbf2015-01-21 10:52:29 -080064
Andrew Brown211d2b62015-02-18 11:12:02 -080065 /**
66 * Request a name on an existing face to verify the forwarder is working and
67 * responding to requests. Note that the name must be served or cached on the
68 * forwarder for this to return true.
69 *
andrewsbrowndb628382015-05-28 10:47:30 -070070 * @param face a {@link Face} to ping
71 * @param name a known {@link Name} that the remote node will answer to
Andrew Brown211d2b62015-02-18 11:12:02 -080072 * @return true if successful, false otherwise
73 */
74 public static boolean ping(Face face, Name name) {
75 // build interest
76 Interest interest = new Interest(name);
77 interest.setInterestLifetimeMilliseconds(DEFAULT_TIMEOUT);
78 interest.setMustBeFresh(true);
Andrew Brown2f1fdbf2015-01-21 10:52:29 -080079
Andrew Brown211d2b62015-02-18 11:12:02 -080080 // send packet
andrewsbrown43b96302015-03-17 21:51:43 +010081 try {
82 Data data = SimpleClient.getDefault().getSync(face, interest);
83 return data != null;
84 } catch (IOException e) {
85 return false;
86 }
Andrew Brown211d2b62015-02-18 11:12:02 -080087 }
Andrew Brown2f1fdbf2015-01-21 10:52:29 -080088
Andrew Brown211d2b62015-02-18 11:12:02 -080089 /**
andrewsbrown8a32f302015-03-24 08:42:46 -070090 * Retrieve the status of the given forwarder; calls /localhost/nfd/status
91 * which requires a local Face (all non-local packets are dropped)
92 *
93 * @param forwarder only a localhost Face
94 * @return the forwarder status object, see
Andrew Browndfa8fc12015-03-25 10:46:47 -070095 * <a href="http://redmine.named-data.net/projects/nfd/wiki/ForwarderStatus">
96 * http://redmine.named-data.net/projects/nfd/wiki/ForwarderStatus</a>.
andrewsbrowndb628382015-05-28 10:47:30 -070097 * @throws IOException if the network request failed
98 * @throws EncodingException if the returned status could not be decoded
andrewsbrown8a32f302015-03-24 08:42:46 -070099 */
andrewsbrowndb628382015-05-28 10:47:30 -0700100 public static ForwarderStatus getForwarderStatus(Face forwarder) throws IOException, EncodingException {
Andrew Brownc5dda702015-04-13 09:36:04 -0700101 Data data = retrieveStatus(forwarder);
andrewsbrown8a32f302015-03-24 08:42:46 -0700102 ForwarderStatus status = new ForwarderStatus();
103 status.wireDecode(data.getContent().buf());
104 return status;
105 }
106
107 /**
Andrew Brown211d2b62015-02-18 11:12:02 -0800108 * Retrieve a list of faces and their status from the given forwarder; calls
109 * /localhost/nfd/faces/list which requires a local Face (all non-local
110 * packets are dropped)
111 *
andrewsbrown8a32f302015-03-24 08:42:46 -0700112 * @param forwarder only a localhost Face
113 * @return a list of face status objects, see
114 * http://redmine.named-data.net/projects/nfd/wiki/FaceMgmt.
andrewsbrowndb628382015-05-28 10:47:30 -0700115 * @throws IOException if the network request failed
116 * @throws ManagementException if the NFD rejected the request
Andrew Brown211d2b62015-02-18 11:12:02 -0800117 */
andrewsbrowndb628382015-05-28 10:47:30 -0700118 public static List<FaceStatus> getFaceList(Face forwarder) throws IOException, ManagementException {
andrewsbrown43b96302015-03-17 21:51:43 +0100119 Data data = retrieveDataSet(forwarder, new Name("/localhost/nfd/faces/list"));
Andrew Brown211d2b62015-02-18 11:12:02 -0800120 return StatusDataset.wireDecode(data.getContent(), FaceStatus.class);
121 }
Andrew Brownc46c1602015-02-18 10:45:56 -0800122
Andrew Brown211d2b62015-02-18 11:12:02 -0800123 /**
Andrew Brown63bed362015-02-18 11:28:50 -0800124 * Retrieve a list of FIB entries and their NextHopRecords from the given
125 * forwarder; calls /localhost/nfd/fib/list which requires a local Face (all
126 * non-local packets are dropped).
127 *
andrewsbrown8a32f302015-03-24 08:42:46 -0700128 * @param forwarder only a localhost Face
129 * @return a list of FIB entries, see
130 * http://redmine.named-data.net/projects/nfd/wiki/FibMgmt#FIB-Dataset.
andrewsbrowndb628382015-05-28 10:47:30 -0700131 * @throws IOException if the network request failed
132 * @throws ManagementException if the NFD rejected the request
Andrew Brown63bed362015-02-18 11:28:50 -0800133 */
andrewsbrowndb628382015-05-28 10:47:30 -0700134 public static List<FibEntry> getFibList(Face forwarder) throws IOException, ManagementException {
andrewsbrown43b96302015-03-17 21:51:43 +0100135 Data data = retrieveDataSet(forwarder, new Name("/localhost/nfd/fib/list"));
Andrew Brown63bed362015-02-18 11:28:50 -0800136 return StatusDataset.wireDecode(data.getContent(), FibEntry.class);
137 }
138
139 /**
Andrew Brown211d2b62015-02-18 11:12:02 -0800140 * Retrieve a list of routing entries from the RIB; calls
141 * /localhost/nfd/rib/list which requires a local Face (all non-local packets
andrewsbrown43b96302015-03-17 21:51:43 +0100142 * are dropped).
Andrew Brown211d2b62015-02-18 11:12:02 -0800143 *
andrewsbrown8a32f302015-03-24 08:42:46 -0700144 * @param forwarder only a localhost Face
145 * @return a list of RIB entries, i.e. routes, see
146 * http://redmine.named-data.net/projects/nfd/wiki/RibMgmt#RIB-Dataset.
andrewsbrowndb628382015-05-28 10:47:30 -0700147 * @throws IOException if the network request failed
148 * @throws ManagementException if the NFD rejected the request
Andrew Brown211d2b62015-02-18 11:12:02 -0800149 */
andrewsbrowndb628382015-05-28 10:47:30 -0700150 public static List<RibEntry> getRouteList(Face forwarder) throws IOException, ManagementException {
andrewsbrown43b96302015-03-17 21:51:43 +0100151 Data data = retrieveDataSet(forwarder, new Name("/localhost/nfd/rib/list"));
Andrew Brown211d2b62015-02-18 11:12:02 -0800152 return StatusDataset.wireDecode(data.getContent(), RibEntry.class);
153 }
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800154
Andrew Brown211d2b62015-02-18 11:12:02 -0800155 /**
andrewsbrown39b0fc92015-05-11 13:44:38 -0700156 * Retrieve the list of strategy choice entries from the NFD; calls
157 * /localhost/nfd/rib/list which requires a local Face (all non-local packets
158 * are dropped).
159 *
160 * @param forwarder only a localhost Face
161 * @return a list of strategy choice entries, i.e. routes, see
162 * http://redmine.named-data.net/projects/nfd/wiki/StrategyChoice.
andrewsbrowndb628382015-05-28 10:47:30 -0700163 * @throws IOException if the network request failed
164 * @throws ManagementException if the NFD rejected the request
andrewsbrown39b0fc92015-05-11 13:44:38 -0700165 */
andrewsbrowndb628382015-05-28 10:47:30 -0700166 public static List<StrategyChoice> getStrategyList(Face forwarder) throws IOException, ManagementException {
andrewsbrown39b0fc92015-05-11 13:44:38 -0700167 Data data = retrieveDataSet(forwarder, new Name("/localhost/nfd/strategy-choice/list"));
168 return StatusDataset.wireDecode(data.getContent(), StrategyChoice.class);
169 }
170
171 /**
Andrew Brownc5dda702015-04-13 09:36:04 -0700172 * Retrieve the {@link KeyLocator} for an NFD.
173 *
174 * @param forwarder only a localhost {@link Face}
175 * @return the {@link KeyLocator} of the NFD's key
andrewsbrowndb628382015-05-28 10:47:30 -0700176 * @throws IOException if the network request failed
177 * @throws ManagementException if the NFD rejected the request or no
178 * KeyLocator was found
Andrew Brownc5dda702015-04-13 09:36:04 -0700179 */
180 public static KeyLocator getKeyLocator(Face forwarder) throws ManagementException, IOException {
181 Data data = retrieveStatus(forwarder);
182 if (!KeyLocator.canGetFromSignature(data.getSignature())) {
183 throw new ManagementException("No key locator available.");
184 }
185 return KeyLocator.getFromSignature(data.getSignature());
186 }
187
188 /**
Andrew Brown211d2b62015-02-18 11:12:02 -0800189 * Helper method to register a new face on the forwarder; as mentioned at
andrewsbrown9a6d7ba2015-03-24 09:53:29 -0700190 * <a href="http://named-data.net/doc/NFD/current/manpages/nfdc.html">http://named-data.net/doc/NFD/current/manpages/nfdc.html</a>,
191 * this is more for debugging; use 'register' instead
Andrew Brown211d2b62015-02-18 11:12:02 -0800192 *
andrewsbrowndb628382015-05-28 10:47:30 -0700193 * @param forwarder only a localhost {@link Face}
194 * @param faceId the ID of the face to add, see
195 * {@link #createFace(net.named_data.jndn.Face, java.lang.String)} for
196 * creating this
197 * @param prefix the {@link Name} of the next-hop prefix
198 * @throws IOException if the network request failed
199 * @throws EncodingException if the NFD response could not be decoded
200 * @throws ManagementException if the NFD rejected the request
Andrew Brown211d2b62015-02-18 11:12:02 -0800201 */
andrewsbrowndb628382015-05-28 10:47:30 -0700202 public static void addNextHop(Face forwarder, int faceId, Name prefix) throws IOException, EncodingException, ManagementException {
Andrew Brown211d2b62015-02-18 11:12:02 -0800203 // build command name
204 Name command = new Name("/localhost/nfd/fib/add-nexthop");
205 ControlParameters parameters = new ControlParameters();
206 parameters.setName(prefix);
207 parameters.setFaceId(faceId);
208 command.append(parameters.wireEncode());
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800209
Andrew Brown211d2b62015-02-18 11:12:02 -0800210 // send the interest
andrewsbrown43b96302015-03-17 21:51:43 +0100211 sendCommand(forwarder, new Interest(command));
Andrew Brown211d2b62015-02-18 11:12:02 -0800212 }
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800213
Andrew Brown211d2b62015-02-18 11:12:02 -0800214 /**
215 * Create a new face on the given forwarder. Ensure the forwarding face is on
216 * the local machine (management requests are to /localhost/...) and that
217 * command signing has been set up (e.g. forwarder.setCommandSigningInfo()).
218 *
andrewsbrowndb628382015-05-28 10:47:30 -0700219 * @param forwarder only a localhost {@link Face}
220 * @param uri a string like "tcp4://host.name.com" (see nfd-status channels
221 * for more protocol options)
222 * @return the newly created face ID
223 * @throws IOException if the network request failed
224 * @throws EncodingException if the NFD response could not be decoded
225 * @throws ManagementException if the NFD rejected the request
Andrew Brown211d2b62015-02-18 11:12:02 -0800226 */
andrewsbrowndb628382015-05-28 10:47:30 -0700227 public static int createFace(Face forwarder, String uri) throws IOException, EncodingException, ManagementException {
Andrew Brown211d2b62015-02-18 11:12:02 -0800228 Name command = new Name("/localhost/nfd/faces/create");
229 ControlParameters parameters = new ControlParameters();
230 parameters.setUri(uri);
231 command.append(parameters.wireEncode());
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800232
Andrew Brown211d2b62015-02-18 11:12:02 -0800233 // send the interest
234 ControlResponse response = sendCommand(forwarder, new Interest(command));
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800235
Andrew Brown211d2b62015-02-18 11:12:02 -0800236 // return
237 return response.getBody().get(0).getFaceId();
238 }
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800239
Andrew Brown211d2b62015-02-18 11:12:02 -0800240 /**
andrewsbrown43b96302015-03-17 21:51:43 +0100241 * Destroy a face on given forwarder. Ensure the forwarding face is on the
242 * local machine (management requests are to /localhost/...) and that command
243 * signing has been set up (e.g. forwarder.setCommandSigningInfo()).
Alexander Afanasyev75d8dfc2015-03-13 16:41:01 -0700244 *
andrewsbrowndb628382015-05-28 10:47:30 -0700245 * @param forwarder only a localhost {@link Face}
246 * @param faceId the ID of the face to destroy
247 * @throws IOException if the network request failed
248 * @throws EncodingException if the NFD response could not be decoded
249 * @throws ManagementException if the NFD rejected the request
Alexander Afanasyev75d8dfc2015-03-13 16:41:01 -0700250 */
andrewsbrowndb628382015-05-28 10:47:30 -0700251 public static void destroyFace(Face forwarder, int faceId) throws IOException, EncodingException, ManagementException {
Alexander Afanasyev75d8dfc2015-03-13 16:41:01 -0700252 Name command = new Name("/localhost/nfd/faces/destroy");
253 ControlParameters parameters = new ControlParameters();
254 parameters.setFaceId(faceId);
255 command.append(parameters.wireEncode());
256
257 // send the interest
andrewsbrown43b96302015-03-17 21:51:43 +0100258 sendCommand(forwarder, new Interest(command));
Alexander Afanasyev75d8dfc2015-03-13 16:41:01 -0700259 }
260
261 /**
andrewsbrowne8e8e852015-03-09 13:48:31 -0700262 * Enable a local control feature on the given forwarder. See
andrewsbrown9a6d7ba2015-03-24 09:53:29 -0700263 * <a href="http://redmine.named-data.net/projects/nfd/wiki/FaceMgmt#Enable-a-LocalControlHeader-feature">http://redmine.named-data.net/projects/nfd/wiki/FaceMgmt#Enable-a-LocalControlHeader-feature</a>
andrewsbrowne8e8e852015-03-09 13:48:31 -0700264 *
andrewsbrowndb628382015-05-28 10:47:30 -0700265 * @param forwarder only a localhost {@link Face}
266 * @param header the control feature to enable
267 * @throws IOException if the network request failed
268 * @throws EncodingException if the NFD response could not be decoded
269 * @throws ManagementException if the NFD rejected the request
andrewsbrowne8e8e852015-03-09 13:48:31 -0700270 */
andrewsbrowndb628382015-05-28 10:47:30 -0700271 public static void enableLocalControlHeader(Face forwarder, LocalControlHeader header) throws IOException, EncodingException, ManagementException {
andrewsbrowne8e8e852015-03-09 13:48:31 -0700272 // build command name
273 Name command = new Name("/localhost/nfd/faces/enable-local-control");
274 ControlParameters parameters = new ControlParameters();
275 parameters.setLocalControlFeature(header.getNumericValue());
276 command.append(parameters.wireEncode());
277
278 // send command and return
andrewsbrown43b96302015-03-17 21:51:43 +0100279 sendCommand(forwarder, new Interest(command));
andrewsbrowne8e8e852015-03-09 13:48:31 -0700280 }
281
282 /**
283 * Disable a local control feature on the given forwarder. See
andrewsbrown9a6d7ba2015-03-24 09:53:29 -0700284 * <a href="http://redmine.named-data.net/projects/nfd/wiki/FaceMgmt#Disable-a-LocalControlHeader-feature">http://redmine.named-data.net/projects/nfd/wiki/FaceMgmt#Disable-a-LocalControlHeader-feature</a>
andrewsbrowne8e8e852015-03-09 13:48:31 -0700285 *
andrewsbrowndb628382015-05-28 10:47:30 -0700286 * @param forwarder only a localhost {@link Face}
287 * @param header the control feature to disable
288 * @throws IOException if the network request failed
289 * @throws EncodingException if the NFD response could not be decoded
290 * @throws ManagementException if the NFD rejected the request
andrewsbrowne8e8e852015-03-09 13:48:31 -0700291 */
andrewsbrowndb628382015-05-28 10:47:30 -0700292 public static void disableLocalControlHeader(Face forwarder, LocalControlHeader header) throws IOException, EncodingException, ManagementException {
andrewsbrowne8e8e852015-03-09 13:48:31 -0700293 // build command name
294 Name command = new Name("/localhost/nfd/faces/disable-local-control");
295 ControlParameters parameters = new ControlParameters();
296 parameters.setLocalControlFeature(header.getNumericValue());
297 command.append(parameters.wireEncode());
298
299 // send command and return
andrewsbrown43b96302015-03-17 21:51:43 +0100300 sendCommand(forwarder, new Interest(command));
andrewsbrowne8e8e852015-03-09 13:48:31 -0700301 }
302
303 /**
Andrew Brown211d2b62015-02-18 11:12:02 -0800304 * Register a route on the forwarder; see
andrewsbrown9a6d7ba2015-03-24 09:53:29 -0700305 * <a href="http://named-data.net/doc/NFD/current/manpages/nfdc.html">http://named-data.net/doc/NFD/current/manpages/nfdc.html</a>
306 * for command-line usage and
307 * <a href="http://redmine.named-data.net/projects/nfd/wiki/RibMgmt">http://redmine.named-data.net/projects/nfd/wiki/RibMgmt</a>
308 * for protocol documentation. Ensure the forwarding face is on the local
309 * machine (management requests are to /localhost/...) and that command
310 * signing has been set up (e.g. forwarder.setCommandSigningInfo()).
Andrew Brown211d2b62015-02-18 11:12:02 -0800311 *
andrewsbrowndb628382015-05-28 10:47:30 -0700312 * @param forwarder only a localhost {@link Face}
313 * @param controlParameters the {@link ControlParameters} command options
314 * @throws IOException if the network request failed
315 * @throws EncodingException if the NFD response could not be decoded
316 * @throws ManagementException if the NFD rejected the request
Andrew Brown211d2b62015-02-18 11:12:02 -0800317 */
andrewsbrowndb628382015-05-28 10:47:30 -0700318 public static void register(Face forwarder, ControlParameters controlParameters) throws IOException, EncodingException, ManagementException {
Andrew Brown211d2b62015-02-18 11:12:02 -0800319 // build command name
320 Name command = new Name("/localhost/nfd/rib/register");
321 command.append(controlParameters.wireEncode());
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800322
Andrew Brown211d2b62015-02-18 11:12:02 -0800323 // send the interest
andrewsbrown43b96302015-03-17 21:51:43 +0100324 sendCommand(forwarder, new Interest(command));
Andrew Brown211d2b62015-02-18 11:12:02 -0800325 }
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800326
Andrew Brown211d2b62015-02-18 11:12:02 -0800327 /**
328 * Register a route on a forwarder; this will create a new face on the
329 * forwarder to the given URI/route pair. See register(Face,
Andrew Brownbd4f4152015-07-13 11:08:18 -0700330 * ControlParameters) for more detailed documentation.
Andrew Brown211d2b62015-02-18 11:12:02 -0800331 *
andrewsbrowndb628382015-05-28 10:47:30 -0700332 * @param forwarder only a localhost {@link Face}
Andrew Brownbd4f4152015-07-13 11:08:18 -0700333 * @param uri the URI (e.g. "tcp4://10.10.2.2:6363") of the remote node; note
334 * that this must be one of the canonical forms described in the wiki
335 * (http://redmine.named-data.net/projects/nfd/wiki/FaceMgmt#TCP) for NFD to
336 * accept the registration--otherwise you will see 400 errors
andrewsbrowndb628382015-05-28 10:47:30 -0700337 * @param route the {@link Name} prefix of the route
338 * @param cost the numeric cost of forwarding along the route
339 * @throws IOException if the network request failed
340 * @throws EncodingException if the NFD response could not be decoded
341 * @throws ManagementException if the NFD rejected the request
Andrew Brown211d2b62015-02-18 11:12:02 -0800342 */
andrewsbrowndb628382015-05-28 10:47:30 -0700343 public static void register(Face forwarder, String uri, Name route, int cost) throws IOException, EncodingException, ManagementException {
Andrew Brown211d2b62015-02-18 11:12:02 -0800344 // create the new face
345 int faceId = createFace(forwarder, uri);
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800346
Andrew Brown211d2b62015-02-18 11:12:02 -0800347 // run base method
andrewsbrown43b96302015-03-17 21:51:43 +0100348 register(forwarder, faceId, route, cost);
Andrew Brown211d2b62015-02-18 11:12:02 -0800349 }
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800350
Andrew Brown211d2b62015-02-18 11:12:02 -0800351 /**
352 * Register a route on a forwarder; this will not create a new face since it
353 * is provided a faceId. See register(Face, ControlParameters) for full
Andrew Brownbd4f4152015-07-13 11:08:18 -0700354 * documentation.
Andrew Brown211d2b62015-02-18 11:12:02 -0800355 *
andrewsbrowndb628382015-05-28 10:47:30 -0700356 * @param forwarder only a localhost {@link Face}
357 * @param faceId the ID of the {@link Face} to assign to the route
358 * @param route the {@link Name} prefix of the route
359 * @param cost the numeric cost of forwarding along the route
360 * @throws IOException if the network request failed
361 * @throws EncodingException if the NFD response could not be decoded
362 * @throws ManagementException if the NFD rejected the request
Andrew Brown211d2b62015-02-18 11:12:02 -0800363 */
andrewsbrowndb628382015-05-28 10:47:30 -0700364 public static void register(Face forwarder, int faceId, Name route, int cost) throws IOException, EncodingException, ManagementException {
Andrew Brown211d2b62015-02-18 11:12:02 -0800365 // build command name
366 ControlParameters parameters = new ControlParameters();
367 parameters.setName(route);
368 parameters.setFaceId(faceId);
369 parameters.setCost(cost);
370 ForwardingFlags flags = new ForwardingFlags();
371 flags.setCapture(true);
372 flags.setChildInherit(true);
373 parameters.setForwardingFlags(flags);
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800374
Andrew Brown211d2b62015-02-18 11:12:02 -0800375 // run base method
andrewsbrown43b96302015-03-17 21:51:43 +0100376 register(forwarder, parameters);
Andrew Brown211d2b62015-02-18 11:12:02 -0800377 }
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800378
Andrew Brown211d2b62015-02-18 11:12:02 -0800379 /**
Andrew Brown63bed362015-02-18 11:28:50 -0800380 * Unregister a route on a forwarder; see
andrewsbrown9a6d7ba2015-03-24 09:53:29 -0700381 * <a href="http://named-data.net/doc/NFD/current/manpages/nfdc.html">http://named-data.net/doc/NFD/current/manpages/nfdc.html</a>
382 * for command-line usage and
383 * <a href="http://redmine.named-data.net/projects/nfd/wiki/RibMgmt">http://redmine.named-data.net/projects/nfd/wiki/RibMgmt</a>
384 * for protocol documentation. Ensure the forwarding face is on the local
385 * machine (management requests are to /localhost/...) and that command
Andrew Brownbd4f4152015-07-13 11:08:18 -0700386 * signing has been set up (e.g. forwarder.setCommandSigningInfo()).
Andrew Brown63bed362015-02-18 11:28:50 -0800387 *
andrewsbrowndb628382015-05-28 10:47:30 -0700388 * @param forwarder only a localhost {@link Face}
389 * @param controlParameters the {@link ControlParameters} command options
390 * @throws IOException if the network request failed
391 * @throws EncodingException if the NFD response could not be decoded
392 * @throws ManagementException if the NFD rejected the request
Andrew Brown63bed362015-02-18 11:28:50 -0800393 */
andrewsbrowndb628382015-05-28 10:47:30 -0700394 public static void unregister(Face forwarder, ControlParameters controlParameters) throws IOException, EncodingException, ManagementException {
Andrew Brown63bed362015-02-18 11:28:50 -0800395 // build command name
396 Name command = new Name("/localhost/nfd/rib/unregister");
397 command.append(controlParameters.wireEncode());
398
399 // send the interest
andrewsbrown43b96302015-03-17 21:51:43 +0100400 sendCommand(forwarder, new Interest(command));
Andrew Brown63bed362015-02-18 11:28:50 -0800401 }
402
403 /**
Andrew Brown07466442015-02-24 09:07:02 -0800404 * Unregister a route on a forwarder; see
andrewsbrown9a6d7ba2015-03-24 09:53:29 -0700405 * <a href="http://named-data.net/doc/NFD/current/manpages/nfdc.html">http://named-data.net/doc/NFD/current/manpages/nfdc.html</a>
406 * for command-line usage and
407 * <a href="http://redmine.named-data.net/projects/nfd/wiki/RibMgmt">http://redmine.named-data.net/projects/nfd/wiki/RibMgmt</a>
408 * for protocol documentation. Ensure the forwarding face is on the local
409 * machine (management requests are to /localhost/...) and that command
Andrew Brownbd4f4152015-07-13 11:08:18 -0700410 * signing has been set up (e.g. forwarder.setCommandSigningInfo().
Andrew Brown07466442015-02-24 09:07:02 -0800411 *
andrewsbrowndb628382015-05-28 10:47:30 -0700412 * @param forwarder only a localhost {@link Face}
413 * @param route the {@link Name} prefix of the route
414 * @throws IOException if the network request failed
415 * @throws EncodingException if the NFD response could not be decoded
416 * @throws ManagementException if the NFD rejected the request
Andrew Brown07466442015-02-24 09:07:02 -0800417 */
andrewsbrowndb628382015-05-28 10:47:30 -0700418 public static void unregister(Face forwarder, Name route) throws IOException, EncodingException, ManagementException {
Andrew Brown07466442015-02-24 09:07:02 -0800419 // build command name
420 ControlParameters controlParameters = new ControlParameters();
421 controlParameters.setName(route);
422
423 // send the interest
andrewsbrown43b96302015-03-17 21:51:43 +0100424 unregister(forwarder, controlParameters);
Andrew Brown07466442015-02-24 09:07:02 -0800425 }
426
427 /**
428 * Unregister a route on a forwarder; see
andrewsbrown9a6d7ba2015-03-24 09:53:29 -0700429 * <a href="http://named-data.net/doc/NFD/current/manpages/nfdc.html">http://named-data.net/doc/NFD/current/manpages/nfdc.html</a>
430 * for command-line usage and
431 * <a href="http://redmine.named-data.net/projects/nfd/wiki/RibMgmt">http://redmine.named-data.net/projects/nfd/wiki/RibMgmt</a>
432 * for protocol documentation. Ensure the forwarding face is on the local
433 * machine (management requests are to /localhost/...) and that command
Andrew Brownbd4f4152015-07-13 11:08:18 -0700434 * signing has been set up (e.g. forwarder.setCommandSigningInfo().
Andrew Brown07466442015-02-24 09:07:02 -0800435 *
andrewsbrowndb628382015-05-28 10:47:30 -0700436 * @param forwarder only a localhost {@link Face}
437 * @param route the {@link Name} prefix of the route
438 * @param faceId the specific ID of the face to remove (more than one face can
439 * be registered to a route)
440 * @throws IOException if the network request failed
441 * @throws EncodingException if the NFD response could not be decoded
442 * @throws ManagementException if the NFD rejected the request
Andrew Brown07466442015-02-24 09:07:02 -0800443 */
andrewsbrowndb628382015-05-28 10:47:30 -0700444 public static void unregister(Face forwarder, Name route, int faceId) throws IOException, EncodingException, ManagementException {
Andrew Brown07466442015-02-24 09:07:02 -0800445 // build command name
446 ControlParameters controlParameters = new ControlParameters();
447 controlParameters.setName(route);
448 controlParameters.setFaceId(faceId);
449
450 // send the interest
andrewsbrown43b96302015-03-17 21:51:43 +0100451 unregister(forwarder, controlParameters);
Andrew Brown07466442015-02-24 09:07:02 -0800452 }
453
454 /**
455 * Unregister a route on a forwarder; see
andrewsbrown9a6d7ba2015-03-24 09:53:29 -0700456 * <a href="http://named-data.net/doc/NFD/current/manpages/nfdc.html">http://named-data.net/doc/NFD/current/manpages/nfdc.html</a>
457 * for command-line usage and
458 * <a href="http://redmine.named-data.net/projects/nfd/wiki/RibMgmt">http://redmine.named-data.net/projects/nfd/wiki/RibMgmt</a>
459 * for protocol documentation. Ensure the forwarding face is on the local
460 * machine (management requests are to /localhost/...) and that command
Andrew Brownbd4f4152015-07-13 11:08:18 -0700461 * signing has been set up (e.g. forwarder.setCommandSigningInfo().
Andrew Brown07466442015-02-24 09:07:02 -0800462 *
andrewsbrowndb628382015-05-28 10:47:30 -0700463 * @param forwarder only a localhost {@link Face}
464 * @param route the {@link Name} prefix of the route
465 * @param uri the URI (e.g. "tcp4://some.host.com") of the remote node (more
466 * than one face can be registered to a route)
467 * @throws IOException if the network request failed
468 * @throws EncodingException if the NFD response could not be decoded
469 * @throws ManagementException if the NFD rejected the request
Andrew Brown07466442015-02-24 09:07:02 -0800470 */
andrewsbrowndb628382015-05-28 10:47:30 -0700471 public static void unregister(Face forwarder, Name route, String uri) throws IOException, EncodingException, ManagementException {
Andrew Brown07466442015-02-24 09:07:02 -0800472 int faceId = -1;
andrewsbrown4c21ea22015-03-09 12:05:03 -0700473 for (FaceStatus face : getFaceList(forwarder)) {
474 if (face.getUri().matches(uri)) {
Andrew Brown07466442015-02-24 09:07:02 -0800475 faceId = face.getFaceId();
476 break;
477 }
478 }
andrewsbrown4c21ea22015-03-09 12:05:03 -0700479
480 if (faceId == -1) {
andrewsbrown43b96302015-03-17 21:51:43 +0100481 throw new ManagementException("Face not found: " + uri);
Andrew Brown07466442015-02-24 09:07:02 -0800482 }
483
484 // send the interest
andrewsbrown43b96302015-03-17 21:51:43 +0100485 unregister(forwarder, route, faceId);
Andrew Brown07466442015-02-24 09:07:02 -0800486 }
487
488 /**
Andrew Brown211d2b62015-02-18 11:12:02 -0800489 * Set a strategy on the forwarder; see
andrewsbrown9a6d7ba2015-03-24 09:53:29 -0700490 * <a href="http://named-data.net/doc/NFD/current/manpages/nfdc.html">http://named-data.net/doc/NFD/current/manpages/nfdc.html</a>
491 * for command-line usage and
492 * <a href="http://redmine.named-data.net/projects/nfd/wiki/StrategyChoice">http://redmine.named-data.net/projects/nfd/wiki/StrategyChoice</a>
Andrew Brown211d2b62015-02-18 11:12:02 -0800493 * for protocol documentation. Ensure the forwarding face is on the local
494 * machine (management requests are to /localhost/...) and that command
495 * signing has been set up (e.g. forwarder.setCommandSigningInfo()).
496 *
andrewsbrowndb628382015-05-28 10:47:30 -0700497 * @param forwarder only a localhost {@link Face}
andrewsbrowncad04eb2015-05-11 13:16:24 -0700498 * @param prefix the {@link Name} prefix
andrewsbrown39b0fc92015-05-11 13:44:38 -0700499 * @param strategy the {@link Name} of the strategy to set, e.g.
500 * /localhost/nfd/strategy/broadcast
andrewsbrowndb628382015-05-28 10:47:30 -0700501 * @throws IOException if the network request failed
502 * @throws EncodingException if the NFD response could not be decoded
503 * @throws ManagementException if the NFD rejected the request
Andrew Brown211d2b62015-02-18 11:12:02 -0800504 */
andrewsbrowndb628382015-05-28 10:47:30 -0700505 public static void setStrategy(Face forwarder, Name prefix, Name strategy) throws IOException, EncodingException, ManagementException {
Andrew Brown211d2b62015-02-18 11:12:02 -0800506 // build command name
507 Name command = new Name("/localhost/nfd/strategy-choice/set");
508 ControlParameters parameters = new ControlParameters();
509 parameters.setName(prefix);
510 parameters.setStrategy(strategy);
511 command.append(parameters.wireEncode());
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800512
Andrew Brown211d2b62015-02-18 11:12:02 -0800513 // send the interest
andrewsbrown43b96302015-03-17 21:51:43 +0100514 sendCommand(forwarder, new Interest(command));
515 }
516
517 /**
andrewsbrowncad04eb2015-05-11 13:16:24 -0700518 * Set a strategy on the forwarder; see
519 * {@link #setStrategy(net.named_data.jndn.Face, net.named_data.jndn.Name, net.named_data.jndn.Name)}
520 * for more information. Ensure the forwarding face is on the local machine
521 * (management requests are to /localhost/...) and that command signing has
522 * been set up (e.g. forwarder.setCommandSigningInfo()).
523 *
524 * @param forwarder only a localhost {@link Face}
525 * @param prefix the {@link Name} prefix
andrewsbrowndb628382015-05-28 10:47:30 -0700526 * @throws IOException if the network request failed
527 * @throws EncodingException if the NFD response could not be decoded
528 * @throws ManagementException if the NFD rejected the request
andrewsbrowncad04eb2015-05-11 13:16:24 -0700529 */
andrewsbrowndb628382015-05-28 10:47:30 -0700530 public static void unsetStrategy(Face forwarder, Name prefix) throws IOException, EncodingException, ManagementException {
andrewsbrowncad04eb2015-05-11 13:16:24 -0700531 // build command name
Andrew Brown37cec242015-05-11 14:24:13 -0700532 Name command = new Name("/localhost/nfd/strategy-choice/unset");
andrewsbrowncad04eb2015-05-11 13:16:24 -0700533 ControlParameters parameters = new ControlParameters();
534 parameters.setName(prefix);
535 command.append(parameters.wireEncode());
536
537 // send the interest
538 sendCommand(forwarder, new Interest(command));
539 }
540
541 /**
Andrew Brownc5dda702015-04-13 09:36:04 -0700542 * Build an interest to retrieve the NFD status.
543 *
544 * @param forwarder only a localhost {@link Face}
545 * @return the status {@link Data} packet
546 * @throws IOException if the retrieval fails
547 */
548 private static Data retrieveStatus(Face forwarder) throws IOException {
549 Interest interest = new Interest(new Name("/localhost/nfd/status"));
550 interest.setMustBeFresh(true);
551 interest.setChildSelector(Interest.CHILD_SELECTOR_RIGHT);
552 interest.setInterestLifetimeMilliseconds(DEFAULT_TIMEOUT);
553 Data data = SimpleClient.getDefault().getSync(forwarder, interest);
554 return data;
555 }
556
557 /**
andrewsbrown43b96302015-03-17 21:51:43 +0100558 * Build an interest to retrieve a segmented data set from the NFD; for
559 * details on the DataSet, see
andrewsbrown9a6d7ba2015-03-24 09:53:29 -0700560 * <a href="http://redmine.named-data.net/projects/nfd/wiki/StatusDataset">http://redmine.named-data.net/projects/nfd/wiki/StatusDataset</a>
andrewsbrown43b96302015-03-17 21:51:43 +0100561 *
Andrew Brownc5dda702015-04-13 09:36:04 -0700562 * @param forwarder the {@link Face} to an NFD
563 * @param datasetName the {@link Name} of the dataset to retrieve
564 * @return the re-assembled {@link Data} packet
565 * @throws IOException if the request fails
566 * @throws ManagementException if the returned TLV is not the expected type
andrewsbrown43b96302015-03-17 21:51:43 +0100567 */
568 public static Data retrieveDataSet(Face forwarder, Name datasetName) throws IOException, ManagementException {
andrewsbrown9a6d7ba2015-03-24 09:53:29 -0700569 // build management Interest packet; see <a href="http://redmine.named-data.net/projects/nfd/wiki/StatusDataset">http://redmine.named-data.net/projects/nfd/wiki/StatusDataset</a>
Andrew Brown0e904e12015-03-17 14:10:29 -0700570 Interest interest = new Interest(datasetName);
andrewsbrown43b96302015-03-17 21:51:43 +0100571 interest.setMustBeFresh(true);
572 interest.setChildSelector(Interest.CHILD_SELECTOR_RIGHT);
573 interest.setInterestLifetimeMilliseconds(DEFAULT_TIMEOUT);
574
575 // send packet
576 Data data = SegmentedClient.getDefault().getSync(forwarder, interest);
577
578 // check for failed request
579 if (data.getContent().buf().get(0) == ControlResponse.TLV_CONTROL_RESPONSE) {
580 throw ManagementException.fromResponse(data.getContent());
581 }
andrewsbrown9a6d7ba2015-03-24 09:53:29 -0700582
andrewsbrown43b96302015-03-17 21:51:43 +0100583 return data;
Andrew Brown211d2b62015-02-18 11:12:02 -0800584 }
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800585
Andrew Brown211d2b62015-02-18 11:12:02 -0800586 /**
587 * Send an interest as a command to the forwarder; this method will convert
588 * the interest to a command interest and block until a response is received
589 * from the forwarder. Ensure the forwarding face is on the local machine
590 * (management requests are to /localhost/...) and that command signing has
591 * been set up (e.g. forwarder.setCommandSigningInfo()).
592 *
andrewsbrown8a32f302015-03-24 08:42:46 -0700593 * @param forwarder only a localhost Face, command signing info must be set
Andrew Brown211d2b62015-02-18 11:12:02 -0800594 * @param interest As described at
andrewsbrown9a6d7ba2015-03-24 09:53:29 -0700595 * <a href="http://redmine.named-data.net/projects/nfd/wiki/ControlCommand,">http://redmine.named-data.net/projects/nfd/wiki/ControlCommand,</a>
596 * the requested interest must have encoded ControlParameters appended to the
Andrew Brown211d2b62015-02-18 11:12:02 -0800597 * interest name
Andrew Brownc5dda702015-04-13 09:36:04 -0700598 * @return a {@link ControlResponse}
Andrew Brown211d2b62015-02-18 11:12:02 -0800599 * @throws java.io.IOException
600 * @throws net.named_data.jndn.encoding.EncodingException
andrewsbrown43b96302015-03-17 21:51:43 +0100601 * @throws com.intel.jndn.management.ManagementException
Andrew Brown211d2b62015-02-18 11:12:02 -0800602 */
andrewsbrown43b96302015-03-17 21:51:43 +0100603 public static ControlResponse sendCommand(Face forwarder, Interest interest) throws IOException, EncodingException, ManagementException {
604 // forwarder must have command signing info set
605 try {
606 forwarder.makeCommandInterest(interest);
607 } catch (SecurityException e) {
608 throw new IllegalArgumentException("Failed to make command interest; ensure command signing info is set on the face.", e);
609 }
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800610
Andrew Brown211d2b62015-02-18 11:12:02 -0800611 // send command packet
andrewsbrown43b96302015-03-17 21:51:43 +0100612 Data data = SimpleClient.getDefault().getSync(forwarder, interest);
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800613
andrewsbrown43b96302015-03-17 21:51:43 +0100614 // decode response
Andrew Brown211d2b62015-02-18 11:12:02 -0800615 ControlResponse response = new ControlResponse();
616 response.wireDecode(data.getContent().buf());
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800617
andrewsbrown43b96302015-03-17 21:51:43 +0100618 // check response for success
619 if (response.getStatusCode() != OK_STATUS) {
620 throw ManagementException.fromResponse(response);
Andrew Brown211d2b62015-02-18 11:12:02 -0800621 }
andrewsbrown43b96302015-03-17 21:51:43 +0100622
623 return response;
Andrew Brown211d2b62015-02-18 11:12:02 -0800624 }
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800625}