ZeroTierOneService.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /*
  2. * ZeroTier One - Global Peer to Peer Ethernet
  3. * Copyright (C) 2012-2013 ZeroTier Networks LLC
  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. * --
  19. *
  20. * ZeroTier may be used and distributed under the terms of the GPLv3, which
  21. * are available at: http://www.gnu.org/licenses/gpl-3.0.html
  22. *
  23. * If you would like to embed ZeroTier into a commercial application or
  24. * redistribute it in a modified binary form, please contact ZeroTier Networks
  25. * LLC. Start here: http://www.zerotier.com/
  26. */
  27. #pragma region Includes
  28. #include "ZeroTierOneService.h"
  29. #pragma endregion
  30. ZeroTierOneService::ZeroTierOneService() :
  31. CServiceBase(ZT_SERVICE_NAME,TRUE,TRUE,FALSE),
  32. _node((ZeroTier::Node *)0)
  33. {
  34. }
  35. ZeroTierOneService::~ZeroTierOneService(void)
  36. {
  37. }
  38. void ZeroTierOneService::threadMain()
  39. throw()
  40. {
  41. restart_node:
  42. try {
  43. {
  44. // start or restart
  45. ZeroTier::Mutex::Lock _l(_lock);
  46. delete _node;
  47. _node = new ZeroTier::Node(ZeroTier::ZT_DEFAULTS.defaultHomePath.c_str(),0,0);
  48. }
  49. switch(_node->run()) {
  50. case ZeroTier::Node::NODE_RESTART_FOR_UPGRADE: {
  51. } break;
  52. case ZeroTier::Node::NODE_UNRECOVERABLE_ERROR: {
  53. std::string err("ZeroTier node encountered an unrecoverable error: ");
  54. const char *r = _node->reasonForTermination();
  55. if (r)
  56. err.append(r);
  57. else err.append("(unknown error)");
  58. err.append(" (restarting in 5 seconds)");
  59. WriteEventLogEntry(const_cast <PSTR>(err.c_str()),EVENTLOG_ERROR_TYPE);
  60. Sleep(5000);
  61. goto restart_node;
  62. } break;
  63. default: // includes normal termination, which will terminate thread
  64. break;
  65. }
  66. } catch ( ... ) {
  67. // sanity check, shouldn't happen since Node::run() should catch all its own errors
  68. // could also happen if we're out of memory though!
  69. WriteEventLogEntry("unexpected exception (out of memory?) (trying again in 5 seconds)",EVENTLOG_ERROR_TYPE);
  70. Sleep(5000);
  71. goto restart_node;
  72. }
  73. _lock.lock();
  74. delete _node;
  75. _node = (ZeroTier::Node *)0;
  76. _lock.unlock();
  77. }
  78. void ZeroTierOneService::OnStart(DWORD dwArgc, LPSTR *lpszArgv)
  79. {
  80. if (_node)
  81. return; // sanity check
  82. try {
  83. _thread = ZeroTier::Thread::start(this);
  84. } catch ( ... ) {
  85. throw (DWORD)ERROR_EXCEPTION_IN_SERVICE;
  86. }
  87. }
  88. void ZeroTierOneService::OnStop()
  89. {
  90. _lock.lock();
  91. ZeroTier::Node *n = _node;
  92. _lock.unlock();
  93. if (n) {
  94. n->terminate(ZeroTier::Node::NODE_NORMAL_TERMINATION,"Windows service stopped");
  95. ZeroTier::Thread::join(_thread);
  96. }
  97. }
  98. void ZeroTierOneService::OnShutdown()
  99. {
  100. // stop thread on system shutdown (if it hasn't happened already)
  101. OnStop();
  102. }