More cleanup, and fix for the extremely unlikely case of identity collision.

This commit is contained in:
Adam Ierymenko 2015-04-15 18:32:25 -07:00
parent f7b1437154
commit ea1859541c
9 changed files with 94 additions and 57 deletions

96
one.cpp
View file

@ -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;
}