ZeroTierOneService.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /*
  2. * Copyright (c)2019 ZeroTier, Inc.
  3. *
  4. * Use of this software is governed by the Business Source License included
  5. * in the LICENSE.TXT file in the project's root directory.
  6. *
  7. * Change Date: 2025-01-01
  8. *
  9. * On the date above, in accordance with the Business Source License, use
  10. * of this software will be governed by version 2.0 of the Apache License.
  11. */
  12. /****/
  13. #pragma region Includes
  14. #if defined(_WIN32) || defined(_WIN64)
  15. #include <winsock2.h>
  16. #include <windows.h>
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include "ZeroTierOneService.h"
  20. #include "../../version.h"
  21. #include "../../include/ZeroTierOne.h"
  22. #include "../../node/Constants.hpp"
  23. #include "../../node/Utils.hpp"
  24. #include "../../osdep/OSUtils.hpp"
  25. #include "../../service/OneService.hpp"
  26. #pragma endregion // Includes
  27. #ifdef ZT_DEBUG_SERVICE
  28. FILE *SVCDBGfile = (FILE *)0;
  29. ZeroTier::Mutex SVCDBGfile_m;
  30. #endif
  31. ZeroTierOneService::ZeroTierOneService() :
  32. CServiceBase(ZT_SERVICE_NAME,TRUE,TRUE,FALSE),
  33. _service((ZeroTier::OneService *)0)
  34. {
  35. #ifdef ZT_DEBUG_SERVICE
  36. SVCDBGfile_m.lock();
  37. if (!SVCDBGfile)
  38. SVCDBGfile = fopen(ZT_DEBUG_SERVICE,"a");
  39. SVCDBGfile_m.unlock();
  40. #endif
  41. ZT_SVCDBG("ZeroTierOneService::ZeroTierOneService()\r\n");
  42. }
  43. ZeroTierOneService::~ZeroTierOneService(void)
  44. {
  45. ZT_SVCDBG("ZeroTierOneService::~ZeroTierOneService()\r\n");
  46. #ifdef ZT_DEBUG_SERVICE
  47. SVCDBGfile_m.lock();
  48. if (SVCDBGfile) {
  49. fclose(SVCDBGfile);
  50. SVCDBGfile = (FILE *)0;
  51. }
  52. SVCDBGfile_m.unlock();
  53. #endif
  54. }
  55. void ZeroTierOneService::threadMain()
  56. throw()
  57. {
  58. ZT_SVCDBG("ZeroTierOneService::threadMain()\r\n");
  59. restart_node:
  60. try {
  61. {
  62. ZeroTier::Mutex::Lock _l(_lock);
  63. delete _service;
  64. _service = (ZeroTier::OneService *)0; // in case newInstance() fails
  65. _service = ZeroTier::OneService::newInstance(_path.c_str(), ZT_DEFAULT_PORT);
  66. }
  67. switch(_service->run()) {
  68. case ZeroTier::OneService::ONE_UNRECOVERABLE_ERROR: {
  69. std::string err("ZeroTier One encountered an unrecoverable error: ");
  70. err.append(_service->fatalErrorMessage());
  71. err.append(" (restarting in 5 seconds)");
  72. WriteEventLogEntry(const_cast <PSTR>(err.c_str()),EVENTLOG_ERROR_TYPE);
  73. Sleep(5000);
  74. } goto restart_node;
  75. case ZeroTier::OneService::ONE_IDENTITY_COLLISION: {
  76. std::string homeDir(ZeroTier::OneService::platformDefaultHomePath());
  77. delete _service;
  78. _service = (ZeroTier::OneService *)0;
  79. std::string oldid;
  80. ZeroTier::OSUtils::readFile((homeDir + ZT_PATH_SEPARATOR_S + "identity.secret").c_str(),oldid);
  81. if (oldid.length()) {
  82. ZeroTier::OSUtils::writeFile((homeDir + ZT_PATH_SEPARATOR_S + "identity.secret.saved_after_collision").c_str(),oldid);
  83. ZeroTier::OSUtils::rm((homeDir + ZT_PATH_SEPARATOR_S + "identity.secret").c_str());
  84. ZeroTier::OSUtils::rm((homeDir + ZT_PATH_SEPARATOR_S + "identity.public").c_str());
  85. }
  86. } goto restart_node;
  87. default: // normal termination
  88. break;
  89. }
  90. } catch ( ... ) {
  91. // sanity check, shouldn't happen since Node::run() should catch all its own errors
  92. // could also happen if we're out of memory though!
  93. WriteEventLogEntry("unexpected exception (out of memory?) (trying again in 5 seconds)",EVENTLOG_ERROR_TYPE);
  94. Sleep(5000);
  95. goto restart_node;
  96. }
  97. {
  98. ZeroTier::Mutex::Lock _l(_lock);
  99. delete _service;
  100. _service = (ZeroTier::OneService *)0;
  101. }
  102. }
  103. void ZeroTierOneService::OnStart(DWORD dwArgc, PSTR *lpszArgv)
  104. {
  105. ZT_SVCDBG("ZeroTierOneService::OnStart()\r\n");
  106. if ((dwArgc > 1)&&(lpszArgv[1])&&(strlen(lpszArgv[1]) > 0)) {
  107. this->_path = lpszArgv[1];
  108. } else {
  109. this->_path = ZeroTier::OneService::platformDefaultHomePath();
  110. }
  111. try {
  112. _thread = ZeroTier::Thread::start(this);
  113. } catch ( ... ) {
  114. throw (DWORD)ERROR_EXCEPTION_IN_SERVICE;
  115. }
  116. }
  117. void ZeroTierOneService::OnStop()
  118. {
  119. ZT_SVCDBG("ZeroTierOneService::OnStop()\r\n");
  120. _lock.lock();
  121. ZeroTier::OneService *s = _service;
  122. _lock.unlock();
  123. if (s) {
  124. s->terminate();
  125. ZeroTier::Thread::join(_thread);
  126. }
  127. }
  128. void ZeroTierOneService::OnShutdown()
  129. {
  130. ZT_SVCDBG("ZeroTierOneService::OnShutdown()\r\n");
  131. // stop thread on system shutdown (if it hasn't happened already)
  132. OnStop();
  133. }
  134. #endif