diff options
Diffstat (limited to 'one.cpp')
-rw-r--r-- | one.cpp | 96 |
1 files changed, 74 insertions, 22 deletions
@@ -69,10 +69,11 @@ #define ZT1_AUTHTOKEN_SECRET_PATH "authtoken.secret" #define ZT1_PID_PATH "zerotier-one.pid" +#define ZT1_CONTROLLER_DB_PATH "controller.db" using namespace ZeroTier; -static OneService *zt1Service = (OneService *)0; +static OneService *volatile zt1Service = (OneService *)0; /****************************************************************************/ /* zerotier-cli personality */ @@ -437,29 +438,11 @@ static void printHelp(const char *cn,FILE *out) { fprintf(out,"ZeroTier One version %d.%d.%d"ZT_EOL_S"(c)2011-2015 ZeroTier, Inc."ZT_EOL_S,ZEROTIER_ONE_VERSION_MAJOR,ZEROTIER_ONE_VERSION_MINOR,ZEROTIER_ONE_VERSION_REVISION); fprintf(out,"Licensed under the GNU General Public License v3"ZT_EOL_S""ZT_EOL_S); - -#ifdef ZT_AUTO_UPDATE - fprintf(out,"Auto-update enabled build, will update from URL:"ZT_EOL_S); - fprintf(out," %s"ZT_EOL_S,ZT_DEFAULTS.updateLatestNfoURL.c_str()); - fprintf(out,"Update authentication signing authorities: "ZT_EOL_S); - int no = 0; - for(std::map< Address,Identity >::const_iterator sa(ZT_DEFAULTS.updateAuthorities.begin());sa!=ZT_DEFAULTS.updateAuthorities.end();++sa) { - if (no == 0) - fprintf(out," %s",sa->first.toString().c_str()); - else fprintf(out,", %s",sa->first.toString().c_str()); - if (++no == 6) { - fprintf(out,ZT_EOL_S); - no = 0; - } - } - fprintf(out,ZT_EOL_S""ZT_EOL_S); -#endif // ZT_AUTO_UPDATE - fprintf(out,"Usage: %s [-switches] [home directory] [-q <query>]"ZT_EOL_S""ZT_EOL_S,cn); fprintf(out,"Available switches:"ZT_EOL_S); fprintf(out," -h - Display this help"ZT_EOL_S); fprintf(out," -v - Show version"ZT_EOL_S); - fprintf(out," -p<port> - Port for UDP (default: 9993)"ZT_EOL_S); + fprintf(out," -p<port> - Port for UDP and TCP/HTTP (default: 9993)"ZT_EOL_S); //fprintf(out," -T<path> - Override root topology, do not authenticate or update"ZT_EOL_S); #ifdef __UNIX_LIKE__ fprintf(out," -d - Fork and run as daemon (Unix-ish OSes)"ZT_EOL_S); @@ -643,8 +626,24 @@ int main(int argc,char **argv) if (!homeDir.length()) homeDir = OneService::platformDefaultHomePath(); - - OSUtils::mkdir(homeDir.c_str()); + if (!homeDir.length()) { + fprintf(stderr,"%s: no home path specified and no platform default available"ZT_EOL_S,argv[0]); + return 1; + } else { + std::vector<std::string> hpsp(Utils::split(homeDir.c_str(),ZT_PATH_SEPARATOR_S,"","")); + std::string ptmp; + if (homeDir[0] == ZT_PATH_SEPARATOR) + ptmp.push_back(ZT_PATH_SEPARATOR); + for(std::vector<std::string>::iterator pi(hpsp.begin());pi!=hpsp.end();++pi) { + if (ptmp.length() > 0) + ptmp.push_back(ZT_PATH_SEPARATOR); + ptmp.append(*pi); + if ((*pi != ".")&&(*pi != "..")) { + if (!OSUtils::mkdir(ptmp)) + throw std::runtime_error("home path does not exist, and could not create"); + } + } + } std::string authToken; { @@ -713,4 +712,57 @@ int main(int argc,char **argv) } #endif // __WINDOWS__ + NetworkController *controller = (NetworkController *)0; +#ifdef ZT_ENABLE_NETWORK_CONTROLLER + try { + controller = new SqliteNetworkController((homeDir + ZT_PATH_SEPARATOR_S + ZT1_CONTROLLER_DB_PATH).c_str()); + } catch (std::exception &exc) { + fprintf(stderr,"%s: failure initializing SqliteNetworkController: %s"ZT_EOL_S,exc.what()); + return 1; + } catch ( ... ) { + fprintf(stderr,"%s: failure initializing SqliteNetworkController: unknown exception"ZT_EOL_S); + return 1; + } +#endif // ZT_ENABLE_NETWORK_CONTROLLER + + unsigned int returnValue = 0; + + try { + for(;;) { + zt1Service = OneService::newInstance(homeDir.c_str(),port,controller,(overrideRootTopology.length() > 0) ? overrideRootTopology.c_str() : (const char *)0); + switch(zt1Service->run()) { + case OneService::ONE_STILL_RUNNING: // shouldn't happen, run() won't return until done + case OneService::ONE_NORMAL_TERMINATION: + break; + case OneService::ONE_UNRECOVERABLE_ERROR: + fprintf(stderr,"%s: fatal error: %s"ZT_EOL_S,argv[0],zt1Service->fatalErrorMessage().c_str()); + returnValue = 1; + break; + case OneService::ONE_IDENTITY_COLLISION: { + delete zt1Service; + zt1Service = (OneService *)0; + std::string oldid; + OSUtils::readFile((homeDir + ZT_PATH_SEPARATOR_S + "identity.secret").c_str(),oldid); + if (oldid.length()) { + OSUtils::writeFile((homeDir + ZT_PATH_SEPARATOR_S + "identity.secret.saved_after_collision").c_str(),oldid); + OSUtils::rm((homeDir + ZT_PATH_SEPARATOR_S + "identity.secret").c_str()); + OSUtils::rm((homeDir + ZT_PATH_SEPARATOR_S + "identity.public").c_str()); + } + } continue; // restart! + } + break; // terminate loop -- normally we don't keep restarting + } + } catch (std::exception &exc) { + fprintf(stderr,"%s: fatal error: %s"ZT_EOL_S,argv[0],exc.what()); + returnValue = 1; + } catch ( ... ) { + fprintf(stderr,"%s: fatal error: unknown exception"ZT_EOL_S,argv[0]); + returnValue = 1; + } + + delete zt1Service; + zt1Service = (OneService *)0; + delete controller; + + return returnValue; } |