void ZeroTierOneService::OnShutdown()
{
    ZT_SVCDBG("ZeroTierOneService::OnShutdown()\r\n");

    // stop thread on system shutdown (if it hasn't happened already)
    OnStop();
}
void ZeroTierOneService::threadMain()
throw()
{
    ZT_SVCDBG("ZeroTierOneService::threadMain()\r\n");

restart_node:
    try {
        {
            ZeroTier::Mutex::Lock _l(_lock);
            delete _service;
            _service = (ZeroTier::OneService *)0; // in case newInstance() fails
            _service = ZeroTier::OneService::newInstance(
                           ZeroTier::OneService::platformDefaultHomePath().c_str(),
                           ZT_DEFAULT_PORT);
        }
        switch(_service->run()) {
        case ZeroTier::OneService::ONE_UNRECOVERABLE_ERROR: {
            std::string err("ZeroTier One encountered an unrecoverable error: ");
            err.append(_service->fatalErrorMessage());
            err.append(" (restarting in 5 seconds)");
            WriteEventLogEntry(const_cast <PSTR>(err.c_str()),EVENTLOG_ERROR_TYPE);
            Sleep(5000);
        }
        goto restart_node;

        case ZeroTier::OneService::ONE_IDENTITY_COLLISION: {
            std::string homeDir(ZeroTier::OneService::platformDefaultHomePath());
            delete _service;
            _service = (ZeroTier::OneService *)0;
            std::string oldid;
            ZeroTier::OSUtils::readFile((homeDir + ZT_PATH_SEPARATOR_S + "identity.secret").c_str(),oldid);
            if (oldid.length()) {
                ZeroTier::OSUtils::writeFile((homeDir + ZT_PATH_SEPARATOR_S + "identity.secret.saved_after_collision").c_str(),oldid);
                ZeroTier::OSUtils::rm((homeDir + ZT_PATH_SEPARATOR_S + "identity.secret").c_str());
                ZeroTier::OSUtils::rm((homeDir + ZT_PATH_SEPARATOR_S + "identity.public").c_str());
            }
        }
        goto restart_node;

        default: // normal termination
            break;
        }
    } catch ( ... ) {
        // sanity check, shouldn't happen since Node::run() should catch all its own errors
        // could also happen if we're out of memory though!
        WriteEventLogEntry("unexpected exception (out of memory?) (trying again in 5 seconds)",EVENTLOG_ERROR_TYPE);
        Sleep(5000);
        goto restart_node;
    }

    {
        ZeroTier::Mutex::Lock _l(_lock);
        delete _service;
        _service = (ZeroTier::OneService *)0;
    }
}
void ZeroTierOneService::OnStart(DWORD dwArgc, LPSTR *lpszArgv)
{
    ZT_SVCDBG("ZeroTierOneService::OnStart()\r\n");

    try {
        _thread = ZeroTier::Thread::start(this);
    } catch ( ... ) {
        throw (DWORD)ERROR_EXCEPTION_IN_SERVICE;
    }
}
Ejemplo n.º 4
0
void ZeroTierOneService::OnStop()
{
	ZT_SVCDBG("ZeroTierOneService::OnStop()\r\n");

	_lock.lock();
	ZeroTier::Node *n = _node;
	_lock.unlock();
	if (n) {
		n->terminate(ZeroTier::Node::NODE_NORMAL_TERMINATION,"Windows service stopped");
		ZeroTier::Thread::join(_thread);
	}
}
ZeroTierOneService::~ZeroTierOneService(void)
{
    ZT_SVCDBG("ZeroTierOneService::~ZeroTierOneService()\r\n");

#ifdef ZT_DEBUG_SERVICE
    SVCDBGfile_m.lock();
    if (SVCDBGfile) {
        fclose(SVCDBGfile);
        SVCDBGfile = (FILE *)0;
    }
    SVCDBGfile_m.unlock();
#endif
}
ZeroTierOneService::ZeroTierOneService() :
    CServiceBase(ZT_SERVICE_NAME,TRUE,TRUE,FALSE),
    _service((ZeroTier::OneService *)0)
{
#ifdef ZT_DEBUG_SERVICE
    SVCDBGfile_m.lock();
    if (!SVCDBGfile)
        SVCDBGfile = fopen(ZT_DEBUG_SERVICE,"a");
    SVCDBGfile_m.unlock();
#endif

    ZT_SVCDBG("ZeroTierOneService::ZeroTierOneService()\r\n");
}
void ZeroTierOneService::OnStop()
{
    ZT_SVCDBG("ZeroTierOneService::OnStop()\r\n");

    _lock.lock();
    ZeroTier::OneService *s = _service;
    _lock.unlock();

    if (s) {
        s->terminate();
        ZeroTier::Thread::join(_thread);
    }
}
Ejemplo n.º 8
0
void ZeroTierOneService::threadMain()
	throw()
{
	ZT_SVCDBG("ZeroTierOneService::threadMain()\r\n");

restart_node:
	try {
		{
			// start or restart
			ZeroTier::Mutex::Lock _l(_lock);
			delete _node;
			_node = new ZeroTier::Node(ZeroTier::ZT_DEFAULTS.defaultHomePath.c_str(),ZT_DEFAULT_UDP_PORT,0,false);
		}
		switch(_node->run()) {
			case ZeroTier::Node::NODE_RESTART_FOR_UPGRADE: {
				// Shut down node
				ZeroTier::Node *n;
				{
				   ZeroTier::Mutex::Lock _l(_lock);
				   n = _node;
				   _node = (ZeroTier::Node *)0;
				}
				std::string msiPath;
				if (n) {
					const char *msiPathTmp = n->reasonForTermination();
					if (msiPathTmp)
						msiPath = msiPathTmp;
				}
				delete n;

				if ((!msiPath.length())||(!ZeroTier::Utils::fileExists(msiPath.c_str()))) {
					WriteEventLogEntry("auto-update failed: no msi path provided by Node",EVENTLOG_ERROR_TYPE);
					Sleep(5000);
					goto restart_node;
				}

				if (!doStartUpgrade(msiPath)) {
					WriteEventLogEntry("auto-update failed: unable to create InstallAndRestartService.bat",EVENTLOG_ERROR_TYPE);
					Sleep(5000);
					goto restart_node;
				}

				// Terminate service to allow updater to update
				Stop();
			}	return;
			case ZeroTier::Node::NODE_UNRECOVERABLE_ERROR: {
				std::string err("ZeroTier node encountered an unrecoverable error: ");
				const char *r = _node->reasonForTermination();
				if (r)
					err.append(r);
				else err.append("(unknown error)");
				err.append(" (restarting in 5 seconds)");
				WriteEventLogEntry(const_cast <PSTR>(err.c_str()),EVENTLOG_ERROR_TYPE);
				Sleep(5000);
				goto restart_node;
			}	break;
			default: // includes normal termination, which will terminate thread
				break;
		}
	} catch ( ... ) {
		// sanity check, shouldn't happen since Node::run() should catch all its own errors
		// could also happen if we're out of memory though!
		WriteEventLogEntry("unexpected exception (out of memory?) (trying again in 5 seconds)",EVENTLOG_ERROR_TYPE);
		Sleep(5000);
		goto restart_node;
	}

	_lock.lock();
	delete _node;
	_node = (ZeroTier::Node *)0;
	_lock.unlock();
}