Skip to content

Commit 8933619

Browse files
committed
Handle arbitrary data items during session initialization
Before, only metrics and IP data items could be sent to peers during session initialization. Extensions may want to pass other data items, so now anything is handled.
1 parent 7fcb0d7 commit 8933619

9 files changed

+244
-52
lines changed

DlepService.h

+20-4
Original file line numberDiff line numberDiff line change
@@ -143,13 +143,14 @@ class DlepService
143143
virtual ReturnStatus destination_down(const DlepMac & mac_address,
144144
const DataItems & data_items = DataItems()) = 0;
145145

146-
/// Notify the DLEP service that the local peer's metrics or IP
147-
/// addresses have changed.
146+
/// Notify the DLEP service that the local peer's metrics, IP
147+
/// addresses, and other data items have changed.
148148
///
149149
/// The DLEP service will issue a Peer Update to the peer with the
150150
/// new information. If there is no extant peer session, the DLEP
151-
/// protocol remembers the metrics/addresses so that they can be
152-
/// sent to a future peer.
151+
/// protocol remembers the data items so that they can be
152+
/// sent to a future peer. The set of data items so remembered is
153+
/// referred to as the set of session initialization data items.
153154
///
154155
/// @param[in] data_items
155156
/// data items (metrics and IP addresses) associated with
@@ -158,6 +159,21 @@ class DlepService
158159
/// @return ok if no error, else as described in DlepService::ReturnStatus
159160
virtual ReturnStatus peer_update(const DataItems & data_items) = 0;
160161

162+
/// Remove data items that were previously given in a peer_update().
163+
///
164+
/// The specified data items are removed from DLEP service's
165+
/// session initialization data items. Future peers will not see
166+
/// these data items sent during session initialization. This
167+
/// does not issue a Peer Update to the peer.
168+
///
169+
/// @param[in] data_items
170+
/// data items associated with the local peer to be removed
171+
///
172+
/// @return ok if no error, else as described in DlepService::ReturnStatus
173+
/// It is not an error to specify a data item that is not in the DlepService's
174+
/// set of session initialization data items.
175+
virtual ReturnStatus peer_remove_data_items(const DataItems & data_items) = 0;
176+
161177
/// Get a list of all existing peer ids.
162178
///
163179
/// @param[out] peers

DlepServiceImpl.cpp

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* Dynamic Link Exchange Protocol (DLEP)
33
*
4-
* Copyright (C) 2015, 2016, 2018 Massachusetts Institute of Technology
4+
* Copyright (C) 2015, 2016, 2018, 2019 Massachusetts Institute of Technology
55
*/
66

77
/// @file
@@ -276,6 +276,15 @@ DlepServiceImpl::peer_update(const LLDLEP::DataItems & data_items)
276276
}
277277
}
278278

279+
DlepServiceImpl::ReturnStatus
280+
DlepServiceImpl::peer_remove_data_items(const DataItems & data_items)
281+
{
282+
boost::recursive_mutex::scoped_lock lock(dlep->mutex);
283+
284+
dlep->local_pdp->remove_data_items(data_items);
285+
return ReturnStatus::ok;
286+
}
287+
279288
DlepServiceImpl::ReturnStatus
280289
DlepServiceImpl::get_peers(std::vector<std::string> & peers)
281290
{

DlepServiceImpl.h

+2
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ class DlepServiceImpl : public LLDLEP::DlepService
4242

4343
ReturnStatus peer_update(const LLDLEP::DataItems & data_items) override;
4444

45+
ReturnStatus peer_remove_data_items(const DataItems & data_items) override;
46+
4547
ReturnStatus get_peers(std::vector<std::string> & peers) override;
4648

4749
ReturnStatus get_peer_info(const std::string & peer_id,

InfoBaseMgr.cpp

+80-23
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* Dynamic Link Exchange Protocol (DLEP)
33
*
4-
* Copyright (C) 2013, 2015, 2016, 2018 Massachusetts Institute of Technology
4+
* Copyright (C) 2013, 2015, 2016, 2018, 2019 Massachusetts Institute of Technology
55
*/
66
#include "InfoBaseMgr.h"
77

@@ -212,22 +212,49 @@ PeerData::PeerData(const std::string & id, const DataItems & initial_data_items,
212212
dlep(dlep),
213213
logger(dlep->logger)
214214
{
215-
for (auto const & di : initial_data_items)
215+
(void)update_data_items_helper(initial_data_items, dlep);
216+
}
217+
218+
PeerData::~PeerData()
219+
{
220+
}
221+
222+
DataItems
223+
PeerData::update_data_items_helper(const DataItems & data_items,
224+
DlepPtr dlep)
225+
{
226+
// We don't need to remember the Status data item because it is
227+
// transient/throwaway state. We'll remember all the other data
228+
// items, though.
229+
DataItemIdType status_id =
230+
dlep->protocfg->get_data_item_id(ProtocolStrings::Status);
231+
232+
// Gather up the data items that might need to be sent to all
233+
// destinations here.
234+
DataItems destination_updates;
235+
236+
for (auto const & di : data_items)
216237
{
217238
if (dlep->protocfg->is_metric(di.id))
218239
{
219240
metric_data_items[di.id] = di;
241+
destination_updates.push_back(di);
220242
}
221243
else if (dlep->protocfg->is_ipaddr(di.id))
222244
{
223245
update_ip_data_items("peer=" + peer_id,
224246
ip_data_items, di, logger);
247+
248+
// IP addresses don't propagate to all destinations,
249+
// so don't add this di to destination_updates
225250
}
226-
}
227-
}
251+
else if (di.id != status_id)
252+
{
253+
other_data_items.push_back(di);
254+
}
255+
} // for each data item
228256

229-
PeerData::~PeerData()
230-
{
257+
return destination_updates;
231258
}
232259

233260
bool
@@ -416,23 +443,7 @@ PeerData::update_data_items(const DataItems & updates, bool tell_peers)
416443
// If we get here, the data items are all OK, so we can apply the changes.
417444

418445
// Collect updates to apply to all destinations here
419-
DataItems destination_updates;
420-
421-
for (auto const & di : updates)
422-
{
423-
if (dlep->protocfg->is_metric(di.id))
424-
{
425-
metric_data_items[di.id] = di;
426-
destination_updates.push_back(di);
427-
}
428-
else if (dlep->protocfg->is_ipaddr(di.id))
429-
{
430-
update_ip_data_items("peer=" + peer_id,
431-
ip_data_items, di, logger);
432-
433-
// IP addresses don't propagate to all destinations
434-
}
435-
} // for each data item in updates
446+
DataItems destination_updates = update_data_items_helper(updates, dlep);
436447

437448
if (!destination_updates.empty())
438449
{
@@ -466,6 +477,41 @@ PeerData::update_data_items(const DataItems & updates, bool tell_peers)
466477
return ProtocolStrings::Success;
467478
}
468479

480+
void
481+
PeerData::remove_data_items(const DataItems & data_items)
482+
{
483+
for (const auto & di : data_items)
484+
{
485+
auto it1 = metric_data_items.find(di.id);
486+
if (it1 != metric_data_items.end())
487+
{
488+
if (it1->second == di)
489+
{
490+
metric_data_items.erase(it1);
491+
continue;
492+
}
493+
}
494+
495+
auto it2 = std::find(ip_data_items.begin(),
496+
ip_data_items.end(), di);
497+
if (it2 != ip_data_items.end())
498+
{
499+
ip_data_items.erase(it2);
500+
continue;
501+
}
502+
503+
504+
auto it3 = std::find(other_data_items.begin(),
505+
other_data_items.end(), di);
506+
if (it3 != other_data_items.end())
507+
{
508+
other_data_items.erase(it3);
509+
continue;
510+
}
511+
}
512+
}
513+
514+
469515
DataItems
470516
PeerData::get_data_items()
471517
{
@@ -481,6 +527,11 @@ PeerData::get_data_items()
481527
return_data_items.push_back(di);
482528
}
483529

530+
for (auto const & di : other_data_items)
531+
{
532+
return_data_items.push_back(di);
533+
}
534+
484535
return return_data_items;
485536
}
486537

@@ -507,6 +558,12 @@ PeerData::log_data_items()
507558
msg << di.to_string();
508559
LOG(DLEP_LOG_DEBUG, msg);
509560
}
561+
562+
for (auto const & di : other_data_items)
563+
{
564+
msg << di.to_string();
565+
LOG(DLEP_LOG_DEBUG, msg);
566+
}
510567
}
511568

512569
void

InfoBaseMgr.h

+16-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* Dynamic Link Exchange Protocol (DLEP)
33
*
4-
* Copyright (C) 2013, 2015, 2016 Massachusetts Institute of Technology
4+
* Copyright (C) 2013, 2015, 2016, 2019 Massachusetts Institute of Technology
55
*/
66
#ifndef _INFO_BASE_MGR_
77
#define _INFO_BASE_MGR_
@@ -18,6 +18,7 @@
1818
#include <map>
1919
#include <vector>
2020
#include <iterator>
21+
#include <algorithm>
2122
#include <libxml/xmlmemory.h>
2223
#include <libxml/parser.h>
2324
#include <boost/thread/recursive_mutex.hpp>
@@ -135,6 +136,7 @@ class PeerData
135136

136137
std::string update_data_items(const LLDLEP::DataItems & updates,
137138
bool tell_peers);
139+
void remove_data_items(const DataItems & data_items);
138140
LLDLEP::DataItems get_data_items();
139141

140142
/// Get a list of all of this peer's data items containing
@@ -154,22 +156,32 @@ class PeerData
154156
std::string find_ip_data_item(const DataItem & ip_data_item) const;
155157

156158
private:
159+
160+
DataItems update_data_items_helper(const DataItems & data_items,
161+
DlepPtr dlep);
162+
157163
/// peer_id is a combination of the TCP remote IP and port of the session
158164
std::string peer_id;
159165

160166
/// Map destination mac to Destination Data
161167
std::map<LLDLEP::DlepMac, DestinationDataPtr> destination_data;
162168

169+
/// The combination of the metric_data_items, ip_data_items, and
170+
/// other_data_items fields below constitute the set of session
171+
/// initialization data items referred to in the DlepService API.
172+
163173
/// Metric data items that this peer supports, and their default
164174
/// values. Only one data item per metric type is allowed, so
165175
/// this is a map.
166176
DataItemMap metric_data_items;
167177

168-
/// IP address data items associated with this destination.
169-
/// There can be multiple IP addresses of each type, so this
170-
/// is a vector.
178+
/// IP address data items associated with this peer. There can be
179+
/// multiple IP addresses of each type, so this is a vector.
171180
DataItems ip_data_items;
172181

182+
// Other data items associated with this peer.
183+
DataItems other_data_items;
184+
173185
/// back-pointer to dlep instance
174186
DlepPtr dlep;
175187

Peer.cpp

+10-7
Original file line numberDiff line numberDiff line change
@@ -1069,10 +1069,13 @@ Peer::send_peer_initialization_response()
10691069

10701070
pm.add_allowed_data_items(dlep->local_pdp->get_data_items());
10711071

1072-
// A freshly built message should be parsable.
1072+
// A freshly built message should be parsable. However, this
1073+
// message contains data items that originated from the client, and
1074+
// they could be invalid. So we parse and validate the message before
1075+
// sending so that problems get logged, but we don't do anything
1076+
// drastic (assert/throw/exit) if it fails.
10731077

1074-
std::string err = pm.parse_and_validate(dlep->is_modem(), __func__);
1075-
assert(err == "");
1078+
pm.parse_and_validate(dlep->is_modem(), __func__);
10761079

10771080
if (should_send_response(ProtocolStrings::Session_Initialization_Response))
10781081
{
@@ -1288,10 +1291,10 @@ Peer::handle_peer_initialization_response(ProtocolMessage & pm)
12881291
/* no-op */
12891292
}
12901293

1291-
DataItems metrics_and_ip_items = pm.get_metrics_and_ipaddrs();
1294+
DataItems data_items = pm.get_data_items();
12921295

1293-
peer_pdp = dlep->info_base_manager->addPeer(peer_id,
1294-
metrics_and_ip_items);
1296+
// filter out Status
1297+
peer_pdp = dlep->info_base_manager->addPeer(peer_id, data_items);
12951298

12961299
// Now that we've received a PEER_INITIALIZATION_Response,
12971300
// we consider this session to be up.
@@ -1301,7 +1304,7 @@ Peer::handle_peer_initialization_response(ProtocolMessage & pm)
13011304

13021305
LLDLEP::PeerInfo peer_info;
13031306
get_info(peer_info);
1304-
peer_info.data_items = metrics_and_ip_items;
1307+
peer_info.data_items = data_items;
13051308
dlep->dlep_client.peer_up(peer_info);
13061309

13071310
// Send the peer all of our destinations

tests/TestClientImpl.h

+3
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,9 @@ class TestClientImpl : public LLDLEP::DlepClient
164164
cv.notify_one();
165165
}
166166

167+
/// Return the information recorded in notify().
168+
T get_result() { return result; }
169+
167170
/// Compare the information recorded in notify() with the expected result.
168171
/// @return true if they are equal, else false
169172
bool check_result(const T & expected_result)

0 commit comments

Comments
 (0)