DeferredPackets.cpp 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. /*
  2. * ZeroTier One - Network Virtualization Everywhere
  3. * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include "Constants.hpp"
  19. #include "DeferredPackets.hpp"
  20. #include "IncomingPacket.hpp"
  21. #include "RuntimeEnvironment.hpp"
  22. #include "Node.hpp"
  23. namespace ZeroTier {
  24. DeferredPackets::DeferredPackets(const RuntimeEnvironment *renv) :
  25. RR(renv),
  26. _waiting(0),
  27. _die(false)
  28. {
  29. }
  30. DeferredPackets::~DeferredPackets()
  31. {
  32. _q_m.lock();
  33. _die = true;
  34. _q_m.unlock();
  35. for(;;) {
  36. _q_s.post();
  37. _q_m.lock();
  38. if (_waiting <= 0) {
  39. _q_m.unlock();
  40. break;
  41. } else {
  42. _q_m.unlock();
  43. }
  44. }
  45. }
  46. bool DeferredPackets::enqueue(IncomingPacket *pkt)
  47. {
  48. {
  49. Mutex::Lock _l(_q_m);
  50. if (_q.size() >= ZT_DEFFEREDPACKETS_MAX)
  51. return false;
  52. _q.push_back(*pkt);
  53. }
  54. _q_s.post();
  55. return true;
  56. }
  57. int DeferredPackets::process()
  58. {
  59. std::list<IncomingPacket> pkt;
  60. _q_m.lock();
  61. if (_die) {
  62. _q_m.unlock();
  63. return -1;
  64. }
  65. while (_q.empty()) {
  66. ++_waiting;
  67. _q_m.unlock();
  68. _q_s.wait();
  69. _q_m.lock();
  70. --_waiting;
  71. if (_die) {
  72. _q_m.unlock();
  73. return -1;
  74. }
  75. }
  76. // Move item from _q list to a dummy list here to avoid copying packet
  77. pkt.splice(pkt.end(),_q,_q.begin());
  78. _q_m.unlock();
  79. try {
  80. pkt.front().tryDecode(RR,true);
  81. } catch ( ... ) {} // drop invalids
  82. return 1;
  83. }
  84. } // namespace ZeroTier