OpenDDS  Snapshot(2023/04/28-20:55)
Checklist.cpp
Go to the documentation of this file.
1 /*
2  *
3  *
4  * Distributed under the OpenDDS License.
5  * See: http://www.opendds.org/license.html
6  */
7 
8 #ifdef OPENDDS_SECURITY
9 
10 #include "Checklist.h"
11 
12 #include "AgentImpl.h"
13 #include "EndpointManager.h"
14 #include "Ice.h"
15 
16 #include "dds/DCPS/Definitions.h"
17 #include <dds/DCPS/LogAddr.h>
18 
20 
21 namespace OpenDDS {
22 namespace ICE {
23 
26 
28  const Candidate& a_remote,
29  bool a_local_is_controlling,
30  bool a_use_candidate)
31  : local(a_local),
32  remote(a_remote),
33  foundation(std::make_pair(a_local.foundation, a_remote.foundation)),
34  local_is_controlling(a_local_is_controlling),
35  priority(compute_priority()),
36  use_candidate(a_use_candidate)
37 {
38  OPENDDS_ASSERT(!a_local.foundation.empty());
39  OPENDDS_ASSERT(!a_remote.foundation.empty());
40 }
41 
42 bool CandidatePair::operator==(const CandidatePair& other) const
43 {
44  return
45  this->local == other.local &&
46  this->remote == other.remote &&
47  this->use_candidate == other.use_candidate;
48 }
49 
51 {
54  return (std::min(g,d) << 32) + 2 * std::max(g,d) + (g > d ? 1 : 0);
55 }
56 
58  const AgentInfo& a_local_agent_info, const AgentInfo& a_remote_agent_info,
59  ACE_UINT64 a_ice_tie_breaker, const MonotonicTimePoint& a_expiration_date)
60  : candidate_pair_(a_candidate_pair), cancelled_(false), expiration_date_(a_expiration_date)
61 {
65 
66  // No local preference, component 1.
67  request_.append_attribute(STUN::make_priority((110 << 24) + (local_priority(a_candidate_pair.local.address) << 8) + ((256 - 1) << 0)));
68 
69  if (a_candidate_pair.local_is_controlling) {
71  }
72 
73  else {
75  }
76 
77  if (a_candidate_pair.local_is_controlling && a_candidate_pair.use_candidate) {
79  }
80 
81  request_.append_attribute(STUN::make_username(a_remote_agent_info.username + ":" + a_local_agent_info.username));
82  request_.password = a_remote_agent_info.password;
85 }
86 
88  const AgentInfo& local, const AgentInfo& remote, ACE_UINT64 a_ice_tie_breaker)
89  : Task(a_endpoint_manager->agent_impl)
90  , endpoint_manager_(a_endpoint_manager)
91  , local_agent_info_(local)
92  , remote_agent_info_(remote)
93  , original_remote_agent_info_(remote)
94  , local_is_controlling_(local.username < remote.username)
95  , ice_tie_breaker_(a_ice_tie_breaker)
96  , nominating_(valid_list_.end())
97  , nominated_(valid_list_.end())
98  , nominated_is_live_(false)
99 {
101 
103 }
104 
106 {
107 }
108 
110 {
111  // Add the candidate pairs.
112  AgentInfo::CandidatesType::const_iterator local_pos = local_agent_info_.candidates.begin();
113  AgentInfo::CandidatesType::const_iterator local_limit = local_agent_info_.candidates.end();
114  for (; local_pos != local_limit; ++local_pos) {
115  AgentInfo::CandidatesType::const_iterator remote_pos = remote_agent_info_.candidates.begin();
116  AgentInfo::CandidatesType::const_iterator remote_limit = remote_agent_info_.candidates.end();
117  for (; remote_pos != remote_limit; ++remote_pos) {
118 #if ACE_HAS_IPV6
119  if ((local_pos->address.is_linklocal() && remote_pos->address.is_linklocal()) ||
120  (!local_pos->address.is_linklocal() && !remote_pos->address.is_linklocal())) {
121  frozen_.push_back(CandidatePair(*local_pos, *remote_pos, local_is_controlling_));
122  }
123 #else
124  frozen_.push_back(CandidatePair(*local_pos, *remote_pos, local_is_controlling_));
125 #endif
126  }
127  }
128 
129  // Sort by priority.
131 
132  // Eliminate duplicates.
133  for (CandidatePairsType::iterator pos = frozen_.begin(), limit = frozen_.end(); pos != limit; ++pos) {
134  CandidatePairsType::iterator test_pos = pos;
135  ++test_pos;
136 
137  while (test_pos != limit) {
138  if (pos->local.base == test_pos->local.base && pos->remote == test_pos->remote) {
139  frozen_.erase(test_pos++);
140  }
141 
142  else {
143  ++test_pos;
144  }
145  }
146  }
147 
148  if (frozen_.size() != 0) {
150  double s = static_cast<double>(frozen_.size());
152  }
153 }
154 
156 {
157  for (CandidatePairsType::const_iterator pos = waiting_.begin(), limit = waiting_.end(); pos != limit; ++pos) {
158  active_foundations.add(pos->foundation);
159  }
160 
161  for (CandidatePairsType::const_iterator pos = in_progress_.begin(), limit = in_progress_.end(); pos != limit; ++pos) {
162  active_foundations.add(pos->foundation);
163  }
164 }
165 
167 {
168  for (CandidatePairsType::const_iterator pos = valid_list_.begin(), limit = valid_list_.end(); pos != limit; ++pos) {
169  OPENDDS_ASSERT(pos->use_candidate);
170  }
171 }
172 
174 {
175  bool flag = false;
176 
177  for (CandidatePairsType::iterator pos = frozen_.begin(), limit = frozen_.end(); pos != limit;) {
178  const CandidatePair& cp = *pos;
179 
180  // The second check allows the Checklist to start work on remote
181  // foundations that also belong to its local agent meaning that the
182  // remote agent is probably another EndpointManager in this
183  // process. They will share an AgentImpl and therefore the same
184  // set of active foundations. This will cause deadlock since both
185  // cannot be the first to use the foundation unless we explicitly
186  // allow it.
188  endpoint_manager_->foundations().count(cp.foundation.second)) {
190  waiting_.push_back(cp);
192  frozen_.erase(pos++);
193  flag = true;
194  } else {
195  ++pos;
196  }
197  }
198 
199  if (flag) {
200  enqueue(MonotonicTimePoint::now());
201  }
202 }
203 
204 void Checklist::unfreeze(const FoundationType& a_foundation)
205 {
206  bool flag = false;
207 
208  for (CandidatePairsType::iterator pos = frozen_.begin(), limit = frozen_.end(); pos != limit;) {
209  const CandidatePair& cp = *pos;
210 
211  if (cp.foundation == a_foundation) {
213  waiting_.push_back(cp);
215  frozen_.erase(pos++);
216  flag = true;
217  } else {
218  ++pos;
219  }
220  }
221 
222  if (flag) {
223  enqueue(MonotonicTimePoint::now());
224  }
225 }
226 
228 {
229  OPENDDS_ASSERT(valid_pair.use_candidate);
230  valid_list_.push_back(valid_pair);
232 }
233 
235 {
236  for (CandidatePairsType::const_iterator pos = waiting_.begin(), limit = waiting_.end(); pos != limit; ++pos) {
237  endpoint_manager_->agent_impl->remove(pos->foundation);
238  }
239 
240  for (CandidatePairsType::const_iterator pos = in_progress_.begin(), limit = in_progress_.end(); pos != limit; ++pos) {
241  endpoint_manager_->agent_impl->remove(pos->foundation);
242  }
243 }
244 
246 {
247  for (AgentInfo::const_iterator pos = local_agent_info_.begin(), limit = local_agent_info_.end(); pos != limit; ++pos) {
248  if (pos->address == address) {
249  candidate = *pos;
250  return true;
251  }
252  }
253 
254  return false;
255 }
256 
258 {
259  for (AgentInfo::const_iterator pos = remote_agent_info_.begin(), limit = remote_agent_info_.end(); pos != limit; ++pos) {
260  if (pos->address == address) {
261  candidate = *pos;
262  return true;
263  }
264  }
265 
266  return false;
267 }
268 
269 void Checklist::add_triggered_check(const CandidatePair& a_candidate_pair)
270 {
271  if (nominating_ != valid_list_.end() || nominated_ != valid_list_.end()) {
272  // Don't generate a check when we are done.
273  return;
274  }
275 
276  CandidatePairsType::iterator pos;
277 
278  pos = std::find(frozen_.begin(), frozen_.end(), a_candidate_pair);
279 
280  if (pos != frozen_.end()) {
281  frozen_.erase(pos);
282  endpoint_manager_->agent_impl->add(a_candidate_pair.foundation);
283  waiting_.push_back(a_candidate_pair);
285  triggered_check_queue_.push_back(a_candidate_pair);
286  return;
287  }
288 
289  pos = std::find(waiting_.begin(), waiting_.end(), a_candidate_pair);
290 
291  if (pos != waiting_.end()) {
292  // Done.
293  return;
294  }
295 
296  pos = std::find(in_progress_.begin(), in_progress_.end(), a_candidate_pair);
297 
298  if (pos != in_progress_.end()) {
299  // Duplicating to waiting.
300  endpoint_manager_->agent_impl->add(a_candidate_pair.foundation);
301  waiting_.push_back(a_candidate_pair);
303  triggered_check_queue_.push_back(a_candidate_pair);
304  return;
305  }
306 
307  pos = std::find(succeeded_.begin(), succeeded_.end(), a_candidate_pair);
308 
309  if (pos != succeeded_.end()) {
310  // Done.
311  return;
312  }
313 
314  pos = std::find(failed_.begin(), failed_.end(), a_candidate_pair);
315 
316  if (pos != failed_.end()) {
317  failed_.erase(pos);
318  endpoint_manager_->agent_impl->add(a_candidate_pair.foundation);
319  waiting_.push_back(a_candidate_pair);
321  triggered_check_queue_.push_back(a_candidate_pair);
322  return;
323  }
324 
325  // Not in checklist.
326  endpoint_manager_->agent_impl->add(a_candidate_pair.foundation);
327  waiting_.push_back(a_candidate_pair);
329  triggered_check_queue_.push_back(a_candidate_pair);
330 }
331 
333 {
334  endpoint_manager_->agent_impl->remove(a_candidate_pair.foundation);
335  // Candidates can be in progress multiple times.
336  CandidatePairsType::iterator pos = std::find(in_progress_.begin(), in_progress_.end(), a_candidate_pair);
337  in_progress_.erase(pos);
338 }
339 
341  const ACE_INET_Addr& remote_address,
342  ACE_UINT32 priority,
343  bool use_candidate)
344 {
345  Candidate remote;
346 
347  if (!get_remote_candidate(remote_address, remote)) {
348  // 7.3.1.3
350  remote_agent_info_.candidates.push_back(remote);
352  }
353 
354  // 7.3.1.4
355  Candidate local;
356  bool flag = get_local_candidate(local_address, local);
357  if (!flag) {
358  // Network addresses may have changed so that local_address is not valid.
359  ACE_ERROR((LM_WARNING, ACE_TEXT("(%P|%t) Checklist::generate_triggered_check: WARNING local_address %C is no longer a local candidate\n"),
360  DCPS::LogAddr(local_address).c_str()));
361  return;
362  }
363 
364  CandidatePair cp(local, remote, local_is_controlling_, use_candidate);
365 
366  if (is_succeeded(cp)) {
367  return;
368  }
369 
370  if (is_in_progress(cp)) {
371  ConnectivityChecksType::iterator pos = std::find(connectivity_checks_.begin(), connectivity_checks_.end(), cp);
372  pos->cancel();
373  }
374 
376  // This can move something from failed to in progress.
377  // In that case, we need to schedule.
379  enqueue(MonotonicTimePoint::now());
380 }
381 
383 {
384  const CandidatePair& cp = cc.candidate_pair();
385 
386  // 7.2.5.3.3
387  // 7.2.5.4
388 
390  succeeded_.push_back(cp);
392 
393  if (cp.use_candidate) {
394  if (local_is_controlling_) {
396  nominating_ = valid_list_.end();
397  OPENDDS_ASSERT(frozen_.empty());
398  OPENDDS_ASSERT(waiting_.empty());
399  }
400 
401  else {
402  nominated_ = std::find(valid_list_.begin(), valid_list_.end(), cp);
403 
404  // This is the case where the use_candidate check succeeded before the normal check.
405  if (nominated_ == valid_list_.end()) {
406  valid_list_.push_front(cp);
407  nominated_ = valid_list_.begin();
408  }
409 
410  while (!frozen_.empty()) {
411  CandidatePair cp = frozen_.front();
412  frozen_.pop_front();
413  failed_.push_back(cp);
414  }
415 
416  while (!waiting_.empty()) {
417  CandidatePair cp = waiting_.front();
418  waiting_.pop_front();
420  failed_.push_back(cp);
421  }
422 
423  triggered_check_queue_.clear();
424  }
425 
426  nominated_is_live_ = true;
427  endpoint_manager_->ice_connect(guids_, nominated_->remote.address);
429 
430  while (!connectivity_checks_.empty()) {
432  connectivity_checks_.pop_front();
433 
434  if (!cc.cancelled()) {
435  failed(cc);
436  }
437 
438  else {
440  }
441 
443  }
444 
445  OPENDDS_ASSERT(frozen_.empty());
446  OPENDDS_ASSERT(waiting_.empty());
448  OPENDDS_ASSERT(in_progress_.empty());
450  }
451 
453 }
454 
456 {
457  const CandidatePair& cp = cc.candidate_pair();
458  // 7.2.5.4
460  failed_.push_back(cp);
462 
464  valid_list_.pop_front();
465  nominating_ = valid_list_.end();
466  }
467 }
468 
469 void Checklist::success_response(const ACE_INET_Addr& local_address,
470  const ACE_INET_Addr& remote_address,
471  const STUN::Message& a_message)
472 {
473  ConnectivityChecksType::iterator pos = std::find(connectivity_checks_.begin(), connectivity_checks_.end(), a_message.transaction_id);
474  OPENDDS_ASSERT(pos != connectivity_checks_.end());
475 
476  ConnectivityCheck const cc = *pos;
477 
478  std::vector<STUN::AttributeType> unknown_attributes = a_message.unknown_comprehension_required_attributes();
479 
480  if (!unknown_attributes.empty()) {
481  ACE_ERROR((LM_WARNING, ACE_TEXT("(%P|%t) Checklist::success_response: WARNING Unknown comprehension required attributes\n")));
482  failed(cc);
483  connectivity_checks_.erase(pos);
484  endpoint_manager_->unset_responsible_checklist(cc.request().transaction_id, rchandle_from(this));
485  return;
486  }
487 
488  if (!a_message.has_fingerprint()) {
489  ACE_ERROR((LM_WARNING, ACE_TEXT("(%P|%t) Checklist::success_response: WARNING No FINGERPRINT attribute\n")));
490  failed(cc);
491  connectivity_checks_.erase(pos);
492  endpoint_manager_->unset_responsible_checklist(cc.request().transaction_id, rchandle_from(this));
493  return;
494  }
495 
496  ACE_INET_Addr mapped_address;
497 
498  if (!a_message.get_mapped_address(mapped_address)) {
499  ACE_ERROR((LM_WARNING, ACE_TEXT("(%P|%t) Checklist::success_response: WARNING No (XOR_)MAPPED_ADDRESS attribute\n")));
500  failed(cc);
501  connectivity_checks_.erase(pos);
502  endpoint_manager_->unset_responsible_checklist(cc.request().transaction_id, rchandle_from(this));
503  return;
504  }
505 
506  if (!a_message.has_message_integrity()) {
507  ACE_ERROR((LM_WARNING, ACE_TEXT("(%P|%t) Checklist::success_response: WARNING No MESSAGE_INTEGRITY attribute\n")));
508  failed(cc);
509  connectivity_checks_.erase(pos);
510  endpoint_manager_->unset_responsible_checklist(cc.request().transaction_id, rchandle_from(this));
511  return;
512  }
513 
514  // Require integrity for checks.
515  if (!a_message.verify_message_integrity(cc.request().password)) {
516  ACE_ERROR((LM_WARNING, ACE_TEXT("(%P|%t) Checklist::success_response: WARNING MESSAGE_INTEGRITY check failed\n")));
517  failed(cc);
518  connectivity_checks_.erase(pos);
519  endpoint_manager_->unset_responsible_checklist(cc.request().transaction_id, rchandle_from(this));
520  return;
521  }
522 
523  // At this point the check will either succeed or fail so remove from the list.
524  connectivity_checks_.erase(pos);
525  endpoint_manager_->unset_responsible_checklist(cc.request().transaction_id, rchandle_from(this));
526 
527  const CandidatePair& cp = cc.candidate_pair();
528 
529  if (remote_address != cp.remote.address || local_address != cp.local.base) {
530  // 7.2.5.2.1 Non-Symmetric Transport Addresses
531  failed(cc);
532  return;
533  }
534 
535  succeeded(cc);
536 
537  if (cp.use_candidate) {
538  return;
539  }
540 
541  // 7.2.5.3.2 Constructing a Valid Pair
542  Candidate local;
543 
544  if (!get_local_candidate(mapped_address, local)) {
545  // 7.2.5.3.1 Discovering Peer-Reflexive Candidates
546  ACE_UINT32 priority;
547  // Our message, no need to check.
548  cc.request().get_priority(priority);
549  local = make_peer_reflexive_candidate(mapped_address, cp.local.base, cp.remote.address, priority);
550  local_agent_info_.candidates.push_back(local);
552  }
553 
554  // The valid pair
555  CandidatePair vp(local, cp.remote, local_is_controlling_, true);
556 
557  add_valid_pair(vp);
558 }
559 
560 void Checklist::error_response(const ACE_INET_Addr& /*local_address*/,
561  const ACE_INET_Addr& /*remote_address*/,
562  const STUN::Message& a_message)
563 {
564  ConnectivityChecksType::iterator pos = std::find(connectivity_checks_.begin(), connectivity_checks_.end(), a_message.transaction_id);
565  OPENDDS_ASSERT(pos != connectivity_checks_.end());
566 
567  ConnectivityCheck const cc = *pos;
568 
569  if (!a_message.has_message_integrity()) {
570  ACE_ERROR((LM_WARNING, ACE_TEXT("(%P|%t) Checklist::error_response: WARNING No MESSAGE_INTEGRITY attribute\n")));
571  // Retry.
572  return;
573  }
574 
575  if (!a_message.verify_message_integrity(cc.request().password)) {
576  // Retry.
577  return;
578  }
579 
580  // We have a verified error response.
581  std::vector<STUN::AttributeType> unknown_attributes = a_message.unknown_comprehension_required_attributes();
582 
583  if (!unknown_attributes.empty()) {
584  ACE_ERROR((LM_WARNING, ACE_TEXT("(%P|%t) Checklist::error_response: WARNING Unknown comprehension required attributes\n")));
585  failed(cc);
586  connectivity_checks_.erase(pos);
587  endpoint_manager_->unset_responsible_checklist(cc.request().transaction_id, rchandle_from(this));
588  return;
589  }
590 
591  if (!a_message.has_fingerprint()) {
592  ACE_ERROR((LM_WARNING, ACE_TEXT("(%P|%t) Checklist::error_response: WARNING No FINGERPRINT attribute\n")));
593  failed(cc);
594  connectivity_checks_.erase(pos);
595  endpoint_manager_->unset_responsible_checklist(cc.request().transaction_id, rchandle_from(this));
596  return;
597  }
598 
599  if (a_message.has_error_code()) {
600  ACE_ERROR((LM_WARNING, ACE_TEXT("(%P|%t) Checklist::error_response: WARNING ")
601  ACE_TEXT("STUN error response code=%d reason=%s\n"),
602  a_message.get_error_code(),
603  a_message.get_error_reason().c_str()));
604 
605  if (a_message.get_error_code() == STUN::UNKNOWN_ATTRIBUTE && a_message.has_unknown_attributes()) {
606  std::vector<STUN::AttributeType> unknown_attributes = a_message.get_unknown_attributes();
607 
608  for (std::vector<STUN::AttributeType>::const_iterator pos = unknown_attributes.begin(),
609  limit = unknown_attributes.end(); pos != limit; ++pos) {
610  ACE_ERROR((LM_WARNING, ACE_TEXT("(%P|%t) Checklist::error_response: WARNING Unknown STUN attribute %d\n"), *pos));
611  }
612  }
613 
614  if (a_message.get_error_code() == STUN::BAD_REQUEST || a_message.get_error_code() == STUN::UNKNOWN_ATTRIBUTE) {
615  // Waiting and/or resending won't fix these errors.
616  failed(cc);
617  connectivity_checks_.erase(pos);
618  endpoint_manager_->unset_responsible_checklist(cc.request().transaction_id, rchandle_from(this));
619  }
620  }
621 
622  else {
623  ACE_ERROR((LM_WARNING, ACE_TEXT("(%P|%t) Checklist::error_response: WARNING STUN error response (no code)\n")));
624  }
625 }
626 
628 {
629  // Triggered checks.
630  if (!triggered_check_queue_.empty()) {
632  triggered_check_queue_.pop_front();
633 
635 
636  waiting_.remove(cp);
637  in_progress_.push_back(cp);
639 
641  connectivity_checks_.push_back(cc);
644  return;
645  }
646 
647  // Ordinary check.
648  if (!waiting_.empty()) {
649  CandidatePair cp = waiting_.front();
650  waiting_.pop_front();
651 
653 
654  in_progress_.push_back(cp);
656 
658  connectivity_checks_.push_back(cc);
661  return;
662  }
663 
664  // Retry.
665  while (!connectivity_checks_.empty()) {
667  connectivity_checks_.pop_front();
668 
669  if (cc.expiration_date() < a_now) {
670  if (!cc.cancelled()) {
671  // Failing can allow nomination to proceed.
672  failed(cc);
673  } else {
675  }
676 
678  continue;
679  }
680 
681  // We leave the cancelled checks in case we get a response.
682  if (!cc.cancelled()) {
683  // Reset the password in the event that it changed.
686  }
687 
688  connectivity_checks_.push_back(cc);
689 
690  // Backoff.
692  break;
693  }
694 
695  // Waiting for the remote or frozen.
697 }
698 
700 {
701  // Nominating check.
702  if (frozen_.empty() &&
703  waiting_.empty() &&
704  // in_progress_.empty() &&
706  !valid_list_.empty() &&
707  nominating_ == valid_list_.end() &&
708  nominated_ == valid_list_.end()) {
709  triggered_check_queue_.clear();
711  nominating_ = valid_list_.begin();
712  }
713 
714  bool flag = false;
715  TimeDuration interval = std::max(check_interval_, ICE::Configuration::instance()->indication_period());
716 
717  if (!triggered_check_queue_.empty() ||
718  !frozen_.empty() ||
719  !waiting_.empty() ||
720  !connectivity_checks_.empty()) {
721  do_next_check(a_now);
722  flag = true;
723  interval = std::min(interval, check_interval_);
724  }
725 
726  if (nominated_ != valid_list_.end()) {
727  // Send an indication.
728  STUN::Message message;
729  message.class_ = STUN::INDICATION;
730  message.method = STUN::BINDING;
731  message.generate_transaction_id();
736  endpoint_manager_->send(nominated_->remote.address, message);
737  flag = true;
738  interval = std::min(interval, ICE::Configuration::instance()->indication_period());
739 
740  // Check that we are receiving indications.
741  const bool before = nominated_is_live_;
743  if (before && !nominated_is_live_) {
745  } else if (!before && nominated_is_live_) {
746  endpoint_manager_->ice_connect(guids_, nominated_->remote.address);
747  }
748  }
749 
750  if (flag) {
751  enqueue(MonotonicTimePoint::now() + interval);
752  }
753 
754  // The checklist has failed. Don't schedule.
755 }
756 
757 void Checklist::add_guid(const GuidPair& a_guid_pair)
758 {
759  guids_.insert(a_guid_pair);
761 }
762 
763 void Checklist::remove_guid(const GuidPair& a_guid_pair)
764 {
765  guids_.erase(a_guid_pair);
767 
768  if (guids_.empty()) {
769  // Cleanup this checklist.
770  fix_foundations();
771 
772  for (ConnectivityChecksType::const_iterator pos = connectivity_checks_.begin(),
773  limit = connectivity_checks_.end(); pos != limit; ++pos) {
774  endpoint_manager_->unset_responsible_checklist(pos->request().transaction_id, rchandle_from(this));
775  }
776 
777  // This should drop our ref-count to zero.
779  }
780 }
781 
782 void Checklist::add_guids(const GuidSetType& a_guids)
783 {
784  for (GuidSetType::const_iterator pos = a_guids.begin(), limit = a_guids.end(); pos != limit; ++pos) {
785  add_guid(*pos);
786  }
787 }
788 
790 {
792 
793  for (GuidSetType::const_iterator pos = guids.begin(), limit = guids.end(); pos != limit; ++pos) {
794  remove_guid(*pos);
795  }
796 }
797 
799 {
800  if (nominated_is_live_ && nominated_ != valid_list_.end()) {
801  return nominated_->remote.address;
802  }
803 
804  return ACE_INET_Addr();
805 }
806 
808 {
810 }
811 
812 
813 } // namespace ICE
814 } // namespace OpenDDS
815 
817 #endif /* OPENDDS_SECURITY */
void add_triggered_check(const CandidatePair &a_candidate_pair)
Definition: Checklist.cpp:269
RcHandle< T > rchandle_from(T *pointer)
Definition: RcHandle_T.h:310
Candidate const local
Definition: Checklist.h:74
#define ACE_ERROR(X)
void add_valid_pair(const CandidatePair &a_valid_pair)
Definition: Checklist.cpp:227
DCPS::TimeDuration check_interval_
Definition: Checklist.h:242
ACE_INET_Addr selected_address() const
Definition: Checklist.cpp:798
bool get_mapped_address(ACE_INET_Addr &address) const
Definition: Stun.cpp:643
void password(const std::string &a_password)
Definition: Checklist.h:124
AgentInfo remote_agent_info_
Definition: Checklist.h:222
void remove_from_in_progress(const CandidatePair &a_candidate_pair)
Definition: Checklist.cpp:332
ConnectivityCheck(const CandidatePair &a_candidate_pair, const AgentInfo &a_local_agent_info, const AgentInfo &a_remote_agent_info, ACE_UINT64 a_ice_tie_breaker, const DCPS::MonotonicTimePoint &a_expiration_date)
Definition: Checklist.cpp:57
void success_response(const ACE_INET_Addr &a_local_address, const ACE_INET_Addr &a_remote_address, const STUN::Message &a_message)
Definition: Checklist.cpp:469
const CandidatePair & candidate_pair() const
Definition: Checklist.h:104
ACE_INET_Addr base
Definition: Ice.h:55
const STUN::Message & request() const
Definition: Checklist.h:108
Attribute make_ice_controlled(ACE_UINT64 ice_tie_breaker)
Definition: Stun.cpp:154
bool contains(const FoundationType &a_foundation) const
Definition: AgentImpl.h:86
void compute_active_foundations(ActiveFoundationSet &a_active_foundations) const
Definition: Checklist.cpp:155
bool is_succeeded(const CandidatePair &a_candidate_pair) const
Definition: Checklist.h:259
bool has_message_integrity() const
Definition: Stun.cpp:692
Attribute make_username(const std::string &username)
Definition: Stun.cpp:84
void unfreeze(const FoundationType &a_foundation)
Definition: AgentImpl.cpp:234
void ice_disconnect(const GuidSetType &guids, const ACE_INET_Addr &addr)
std::pair< std::string, std::string > FoundationType
Definition: Checklist.h:34
ACE_UINT64 compute_priority()
Definition: Checklist.cpp:50
#define OPENDDS_ASSERT(C)
Definition: Definitions.h:72
void enqueue(const DCPS::MonotonicTimePoint &release_time)
Definition: Task.cpp:19
void ice_connect(const GuidSetType &guids, const ACE_INET_Addr &addr)
GuidSetType guids() const
Definition: Checklist.h:198
CandidatePairsType in_progress_
Definition: Checklist.h:230
void add(const FoundationType &a_foundation)
Definition: Checklist.h:38
Candidate make_peer_reflexive_candidate(const ACE_INET_Addr &address, const ACE_INET_Addr &base, const ACE_INET_Addr &server_address, ACE_UINT32 priority)
Definition: Ice.cpp:88
void generate_transaction_id()
Definition: Stun.cpp:606
std::vector< AttributeType > get_unknown_attributes() const
Definition: Stun.cpp:786
void checklist_period(const DCPS::TimeDuration &x)
Definition: RTPS/ICE/Ice.h:91
Attribute make_use_candidate()
Definition: Stun.cpp:132
const ACE_UINT16 UNKNOWN_ATTRIBUTE
Definition: Stun.h:53
CandidatePairsType waiting_
Definition: Checklist.h:229
ACE_INET_Addr address
Definition: Ice.h:46
Candidate const remote
Definition: Checklist.h:75
void T_a(const DCPS::TimeDuration &x)
Definition: RTPS/ICE/Ice.h:73
void failed(const ConnectivityCheck &a_connectivity_check)
Definition: Checklist.cpp:455
bool has_unknown_attributes() const
Definition: Stun.cpp:775
void nominated_ttl(const DCPS::TimeDuration &x)
Definition: RTPS/ICE/Ice.h:109
void send(const ACE_INET_Addr &address, const STUN::Message &message)
Checklist(EndpointManager *a_endpoint, const AgentInfo &a_local, const AgentInfo &a_remote, ACE_UINT64 a_ice_tie_breaker)
Definition: Checklist.cpp:87
CandidatePairsType frozen_
Definition: Checklist.h:228
bool const local_is_controlling_
Definition: Checklist.h:224
CandidatesType::const_iterator const_iterator
Definition: Ice.h:72
const ACE_UINT16 BAD_REQUEST
Definition: Stun.h:51
DCPS::MonotonicTimePoint last_indication_
Definition: Checklist.h:241
ACE_UINT16 get_error_code() const
Definition: Stun.cpp:753
bool get_local_candidate(const ACE_INET_Addr &a_address, Candidate &a_candidate)
Definition: Checklist.cpp:245
ACE_UINT32 local_priority(const ACE_INET_Addr &addr)
Definition: Ice.cpp:56
STL namespace.
void do_next_check(const DCPS::MonotonicTimePoint &a_now)
Definition: Checklist.cpp:627
std::string username
Definition: Ice.h:77
CandidatePairsType succeeded_
Definition: Checklist.h:231
CandidatesType candidates
Definition: Ice.h:74
std::string foundation
Definition: Ice.h:48
TimePoint_T< MonotonicClock > MonotonicTimePoint
Definition: TimeTypes.h:51
ConnectivityChecksType connectivity_checks_
Definition: Checklist.h:245
CandidatePairsType::const_iterator nominated_
Definition: Checklist.h:239
Attribute make_ice_controlling(ACE_UINT64 ice_tie_breaker)
Definition: Stun.cpp:146
bool const local_is_controlling
Definition: Checklist.h:77
DCPS::TimeDuration max_check_interval_
Definition: Checklist.h:243
LM_WARNING
void succeeded(const ConnectivityCheck &a_connectivity_check)
Definition: Checklist.cpp:382
Attribute make_message_integrity()
Definition: Stun.cpp:92
bool has_error_code() const
Definition: Stun.cpp:742
ACE_TEXT("TCP_Factory")
Attribute make_fingerprint()
Definition: Stun.cpp:139
bool get_remote_candidate(const ACE_INET_Addr &a_address, Candidate &a_candidate)
Definition: Checklist.cpp:257
static bool priority_sorted(const CandidatePair &x, const CandidatePair &y)
Definition: Checklist.h:90
const_iterator end() const
Definition: Ice.h:85
unsigned long long ACE_UINT64
void append_attribute(const Attribute &attribute)
Definition: Stun.h:195
void remove_guid(const GuidPair &a_guid_pair)
Definition: Checklist.cpp:763
void execute(const DCPS::MonotonicTimePoint &a_now)
Definition: Checklist.cpp:699
std::string get_error_reason() const
Definition: Stun.cpp:764
void check_invariants() const
Definition: Checklist.cpp:166
void remove(const FoundationType &a_foundation)
Definition: AgentImpl.cpp:228
static Configuration * instance()
Definition: Ice.cpp:109
FoundationType const foundation
Definition: Checklist.h:76
void generate_triggered_check(const ACE_INET_Addr &a_local_address, const ACE_INET_Addr &a_remote_address, ACE_UINT32 a_priority, bool a_use_candidate)
Definition: Checklist.cpp:340
const_iterator begin() const
Definition: Ice.h:81
#define OPENDDS_END_VERSIONED_NAMESPACE_DECL
bool operator==(const CandidatePair &a_other) const
Definition: Checklist.cpp:42
void add_guids(const GuidSetType &a_guids)
Definition: Checklist.cpp:782
CandidatePairsType::const_iterator nominating_
Definition: Checklist.h:238
std::string password
Definition: Stun.h:242
EndpointManager *const endpoint_manager_
Definition: Checklist.h:219
AgentInfo local_agent_info_
Definition: Checklist.h:221
bool verify_message_integrity(const std::string &password) const
Definition: Stun.cpp:703
std::string password
Definition: Ice.h:78
const FoundationSet & foundations() const
CandidatePair(const Candidate &a_local, const Candidate &a_remote, bool a_local_is_controlling, bool a_use_candidate=false)
Definition: Checklist.cpp:27
ACE_UINT64 const ice_tie_breaker_
Definition: Checklist.h:225
CandidatePairsType valid_list_
Definition: Checklist.h:236
void add_guid(const GuidPair &a_guid_pair)
Definition: Checklist.cpp:757
void error_response(const ACE_INET_Addr &a_local_address, const ACE_INET_Addr &a_remote_address, const STUN::Message &a_message)
Definition: Checklist.cpp:560
std::vector< AttributeType > unknown_comprehension_required_attributes() const
Definition: Stun.cpp:616
bool is_in_progress(const CandidatePair &a_candidate_pair) const
Definition: Checklist.h:264
TransactionId transaction_id
Definition: Stun.h:186
The Internal API and Implementation of OpenDDS.
Definition: AddressCache.h:28
void unset_responsible_checklist(const STUN::TransactionId &a_transaction_id, ChecklistPtr a_checklist)
CandidatePairsType failed_
Definition: Checklist.h:232
ACE_UINT32 priority
Definition: Ice.h:50
Attribute make_priority(ACE_UINT32 priority)
Definition: Stun.cpp:124
void set_responsible_checklist(const STUN::TransactionId &a_transaction_id, ChecklistPtr a_checklist)
void add(const FoundationType &a_foundation)
Definition: AgentImpl.h:91
DCPS::MonotonicTimePoint expiration_date() const
Definition: Checklist.h:120
std::set< GuidPair > GuidSetType
Definition: RTPS/ICE/Ice.h:39
bool candidates_sorted(const Candidate &x, const Candidate &y)
Definition: Ice.cpp:21
CandidatePairsType triggered_check_queue_
Definition: Checklist.h:234
size_t remote_peer_reflexive_counter()
Definition: AgentImpl.h:81
bool has_fingerprint() const
Definition: Stun.cpp:797