Beispiel #1
0
void svServer::CreateStorageThreads(void)
{
	map<string, svConfOrganization *> org;
	org = conf->GetOrganizations();
	map<string, svConfOrganization *>::iterator oi;
	for (oi = org.begin(); oi != org.end(); oi++) {
		map<svConfDatabaseType, svConfDatabase *> db;
		db = oi->second->GetDatabases();
		if (!db.size()) continue;
		
		svThreadStorage *thread;
		thread = new svThreadStorage(oi->second->GetDevice(),
			oi->first, oi->second->GetKeyCacheTTL());
		map<svConfDatabaseType, svConfDatabase *>::iterator di;
		for (di = db.begin(); di != db.end(); di++)
			thread->AddStorageEngine(*(di->second));
		try {
			thread->SetDefaultDest(this);
			thread->Start();
		} catch (runtime_error &e) {
			svError("%s: Error starting storage engine: %s",
				name.c_str(), e.what());
			delete thread;
			continue;
		}
		storage[oi->first] = thread;
	}
}
Beispiel #2
0
void svServer::LoadKeyRing(void)
{
	for (map<string, svKeyRing *>::iterator i = key_ring.begin();
		i != key_ring.end(); i++) delete i->second;
	key_ring.clear();

	map<string, svConfOrganization *> org;
	org = conf->GetOrganizations();
	map<string, svConfOrganization *>::iterator oi;
	for (oi = org.begin(); oi != org.end(); oi++) {
		string key_dir = oi->second->GetKeyDir();
		svKeyRing *kr = NULL;
		try {
			kr = new svKeyRing(key_dir);
		} catch (runtime_error &e) {
			svError("%s: %s", name.c_str(), e.what());
			continue;
		}
		if (!kr->GetCount()) {
			delete kr;
			continue;
		}
		key_ring[oi->first] = kr;
	}
}
Beispiel #3
0
void svThreadStorage::AddStorageEngine(const svConfDatabase &conf)
{
	svStorageEngine *se = NULL;

	switch (conf.GetType()) {
#ifdef HAVE_LIBDB
	case svDT_BDB:
		se = new svStorageEngineBerkeley(conf);
		break;
#endif // HAVE_LIBDB

#ifdef HAVE_LIBPQ
	case svDT_PGSQL:
		se = new svStorageEnginePostgreSQL(conf);
		break;
#endif // HAVE_LIBPQ

#ifdef HAVE_LIBMYSQLCLIENT
	case svDT_MYSQL:
		se = new svStorageEngineMySQL(conf);
		break;
#endif // HAVE_LIBMYSQLCLIENT
	default:
		svError("%s: WARNING: Unsupported storage engine type: %d",
			name.c_str(), conf.GetType());
		break;
	}

	if (se) engine.push_back(se);
}
Beispiel #4
0
svRSAKey::svRSAKey(const string &pem)
	: svObject("svRSAKey"), type(svRSA_TYPE_NULL), key(NULL), mtime(0)
{
	struct stat key_stat;
	if (stat(pem.c_str(), &key_stat) == -1)
		throw svExRSAKeyStat(pem, strerror(errno));
	mtime = key_stat.st_mtime;

	FILE *h_key = fopen(pem.c_str(), "r");
	if (!h_key) throw svExRSAKeyOpen(pem, strerror(errno));

	if ((key = PEM_read_RSA_PUBKEY(h_key, NULL, NULL, NULL)))
		type = svRSA_TYPE_PUBLIC;
	else {
		rewind(h_key);

		if ((key = PEM_read_RSAPrivateKey(h_key, NULL, NULL, NULL)))
			type = svRSA_TYPE_PRIVATE;
		else {
			ERR_load_crypto_strings();
			svError("%s: %s: %s", name.c_str(), pem.c_str(),
				ERR_error_string(ERR_get_error(), NULL));
		}
	}

	fclose(h_key);

	if (type == svRSA_TYPE_NULL) throw svExRSAKeyInvalid(pem);
	name = pem;
}
Beispiel #5
0
void svThreadStorage::UpdatePoolClient(	
	svEventPoolClientUpdate *request)
{
	string state("unknown");
	switch (request->GetState()) {
	case svPCS_IDLE:
		state = "idle";
		break;
	case svPCS_INUSE:
		state = "in-use";
		break;
	case svPCS_OFFLINE:
		state = "offline";
		break;
	};
	
	svDebug("%s: Update pool client: %s %s: %s",
		name.c_str(), request->GetPoolName().c_str(),
		request->GetDevice().c_str(), state.c_str());

	for (vector<svStorageEngine *>::iterator i = engine.begin();
		i != engine.end(); i++) {
		if ((*i)->GetType() != svDT_PGSQL &&
			(*i)->GetType() != svDT_MYSQL) continue;
		try {
			(*i)->UpdatePoolClient(node, request->GetPoolName(),
				request->GetDevice(), org, request->GetState());
			continue;
		} catch (svExStorageRecordNotFound &e) {
		} catch (runtime_error &e) {
			svError("%s: %s", name.c_str(), e.what());
			continue;
		}

		try {
			(*i)->InsertPoolClient(node, request->GetPoolName(),
				request->GetDevice(), org, request->GetState());
		} catch (runtime_error &e) {
			svError("%s: %s", name.c_str(), e.what());
			continue;
		}
	}
}
Beispiel #6
0
void svServer::ClientSocketRead(svSocket *skt)
{
	bool found = false;
	map<string, map<string, vector<svPoolClient *> > >::iterator io;
	io = pool.find(skt->GetOrganization());

	if (io != pool.end()) {
		map<string, vector<svPoolClient *> >::iterator id;
		id = io->second.find(skt->GetDevice());

		if (id != io->second.end()) {
			vector<svPoolClient *>::iterator ic;

			for (ic = id->second.begin();
				ic != id->second.end(); ic++) {
				if ((*ic)->GetSocket() != skt) {
					svError("%s: %s: Pool client active: %s",
						name.c_str(), io->first.c_str(), id->first.c_str());
					continue;
				}
				svError("%s: %s: Pool client hung-up: %s",
					name.c_str(), io->first.c_str(), id->first.c_str());
				map<string, svThreadStorage *>::iterator is;
				is = storage.find((*ic)->GetOrganization());
				if (is != storage.end()) {
					svEventServer::GetInstance()->Dispatch(
						new svEventPoolClientUpdate(
							is->second, (*ic)->GetName(),
							(*ic)->GetDevice(), svPCS_OFFLINE));
				}
				(*ic)->GetSocket(true);
				delete (*ic);
				id->second.erase(ic);
				found = true;
				break;
			}

			if (!id->second.size()) io->second.erase(id);
		}
	}
	if (found) throw svExSocketHangup();
}
Beispiel #7
0
void svServer::CreateSessionAccept(svSocket *skt)
{
	svSessionServerAccept *server = NULL;
	try {
		server = new svSessionServerAccept(skt);
		CreateSession(server);
	} catch (runtime_error &e) {
		svError("%s: Error starting session: %s", name.c_str(), e.what());
		if (server) delete server;
	}
}
Beispiel #8
0
void svServer::CreateSessionConnect(svSocket *skt, svConfFrontDoor *sfd)
{
	svSessionServerConnect *server = NULL;
	try {
		server = new svSessionServerConnect(skt, *sfd);
		CreateSession(server);
	} catch (runtime_error &e) {
		svError("%s: Error starting session: %s", name.c_str(), e.what());
		if (server) delete server;
	}
}
Beispiel #9
0
static void sv_crypto_lock(int mode, int n, const char *file, int line)
{
	if (svCrypto::mutex_crypto == NULL) {
		svError("%s: mutex_crypto not initialized!", __func__);
		// TODO: throw...
		return;
	}

	if (mode & CRYPTO_LOCK)
		pthread_mutex_lock(svCrypto::mutex_crypto[n]);
	else
		pthread_mutex_unlock(svCrypto::mutex_crypto[n]);
}
Beispiel #10
0
void svThreadStorage::PurgePoolClients(void)
{
	for (vector<svStorageEngine *>::iterator i = engine.begin();
		i != engine.end(); i++) {
		if ((*i)->GetType() != svDT_PGSQL &&
			(*i)->GetType() != svDT_MYSQL) continue;
		try {
			(*i)->PurgePoolClients(node, org);
		} catch (runtime_error &e) {
			svError("%s: %s", name.c_str(), e.what());
		}
	}
}
Beispiel #11
0
void svServer::HostKeyResult(svEventHostKeyResult *result)
{
	map<string, svThreadStorage *>::iterator i;
	i = storage.find(result->GetOrganization());

	if (i == storage.end()) {
		svError("%s: Organization storage engine not found: %s",
			name.c_str(), result->GetOrganization().c_str());
		// TODO: throw...
		return;
	}

	i->second->BroadcastHostKeyResult(result);
}
Beispiel #12
0
int main(int argc, char *argv[])
{
	int rc = 0;
	svEventServer *evt_server = NULL;
	svConfServer *conf = NULL;
	svServer *server = NULL;
	svOutput output;

	try {
		conf = new svConfServer(argc, argv);
		evt_server = new svEventServer();
		server = new svServer(conf);
		server->Start();
	} catch (svExConfUsageRequest &e) {
	} catch (svExConfSaveRequest &e) {
	} catch (svExConfOpen &e) {
		svError(e.what());
		rc = 1;
	} catch (svExConfParse &e) {
		svError("%s: row: %d, col: %d, byte: 0x%02x",
			e.what(), e.row, e.col, e.byte);
		rc = 1;
	} catch (runtime_error &e) {
		svError("Run-time exception: %s", e.what());
		rc = 1;
	} catch (exception &e) {
		svError("Uncaught exception: %s", e.what());
		rc = 1;
	}

	if (server) delete server;
	else if (conf) delete conf;
	if (evt_server) delete evt_server;

	closelog();
	return rc;
}
Beispiel #13
0
void svExec::Exited(int status)
{
#if !defined(__WIN32__) && !defined(__ANDROID__)
    pid = -1;
    exited = true;
    if (WIFEXITED(status)) {
        svLog("%s: Exited with code: %d",
            name.c_str(), WEXITSTATUS(status));
    } else if (WIFSIGNALED(status)) {
        svLog("%s: Exited by signal: %s",
            name.c_str(), strsignal(WTERMSIG(status)));
    }
    else svError("%s: Did not exit normally");
#endif
}
Beispiel #14
0
void svExec::Terminate(void)
{
#if !defined(__WIN32__) && !defined(__ANDROID__)
    if (pid == -1) return;
    if (skt) {
        delete skt;
        skt = NULL;
    }

    struct timeval tv_now, tv_timeout;
    gettimeofday(&tv_timeout, NULL);
    tv_timeout.tv_sec += _SUVA_APP_WAIT;

    svEvent *event;
    for ( ;; ) {
        while ((event = PopWaitEvent(1000))) {
            switch (event->GetId()) {
            case svEVT_QUIT:
                return;

            case svEVT_CHILD_EXIT:
                svEventChildExit *event_child;
                event_child = (svEventChildExit *)event;
                if (event_child->GetPid() != pid)
                    break;
                Exited(event_child->GetStatus());
                delete event_child;
                return;

            default:
                break;
            }

            delete event;
        }

        gettimeofday(&tv_now, NULL);
        if (tv_now.tv_sec > tv_timeout.tv_sec) {
            kill(pid, SIGTERM);
            svError("%s: Timed-out waiting on application to exit: %d",
                name.c_str(), pid);
            break;
        }
    }
#endif
}
Beispiel #15
0
void svServer::PoolClientLoad(svEventPoolClientLoad *event)
{
	svPoolClient *client = NULL;

	map<string, map<string, vector<svPoolClient *> > >::iterator io;
	io = pool.find(event->GetOrganization());
	if (io != pool.end()) {
		map<string, vector<svPoolClient *> >::iterator id;
		id = io->second.find(event->GetDevice());
		if (id != io->second.end() && id->second.size()) {
			client = id->second.back();
			id->second.pop_back();
			if (!id->second.size()) io->second.erase(id);
		}
	}

	if (client) {
		for (vector<svSocket *>::iterator i = skt_client.begin();
			i != skt_client.end(); i++) {
			if ((*i) != client->GetSocket()) continue;
			skt_client.erase(i);
			skt_set.RemoveForRead(client->GetSocket());
			break;
		}
		svLog("%s: Pool client found: %s %s [%s]",
			name.c_str(), client->GetName().c_str(),
			client->GetDevice().c_str(), event->GetOrganization().c_str());
		map<string, svThreadStorage *>::iterator i;
		i = storage.find(event->GetOrganization());
		if (i != storage.end()) {
			svEventServer::GetInstance()->Dispatch(
				new svEventPoolClientUpdate(
					i->second, client->GetName(),
					event->GetDevice(), svPCS_INUSE));
		}
	}
	else {
		svError("%s: %s: Pool client not found: %s", name.c_str(),
			event->GetOrganization().c_str(), event->GetDevice().c_str());
	}

	svEventServer::GetInstance()->Dispatch(
		new svEventPoolClientLoad(this, event->GetSource(), client));
}
Beispiel #16
0
static void db_panic(DB_ENV *db_env, int errval)
{
	svError("db: panic: %s", db_strerror(errval));
}
Beispiel #17
0
void svThreadStorage::GetHostKey(svEventHostKeyRequest *request)
{
	svHostKey key;

	for (vector<svStorageEngine *>::iterator i = engine.begin();
		i != engine.end(); i++) {
		if ((*i)->GetType() != svDT_BDB) continue;
		try {
			(*i)->GetHostKey(request->GetDevice(), org, key);
		} catch (svExStorageRecordNotFound &e) {
			svDebug("%s: %s", org.c_str(), e.what());
			continue;
		} catch (runtime_error &e) {
			svError("%s: %s", org.c_str(), e.what());
			continue;
		}

		if (!key.HasExpired(hostkey_ttl)) {
			svEventServer::GetInstance()->Dispatch(
				new svEventHostKeyResult(this, NULL,
					request->GetDevice(),
					request->GetOrganization(), key));
			svDebug("%s: Using cached hostkey for: %s",
				org.c_str(), request->GetDevice().c_str());
			return;
		}
	}

	for (vector<svStorageEngine *>::iterator i = engine.begin();
		i != engine.end(); i++) {
		if ((*i)->GetType() != svDT_PGSQL &&
			(*i)->GetType() != svDT_MYSQL) continue;
		try {
			(*i)->GetHostKey(request->GetDevice(), org, key);
#if 0
		} catch (svExStorageConnect &e) {
			svError("%s: svExStorageConnect", org.c_str());
			continue;
		} catch (svExStorageDisconnect &e) {
			svError("%s: svExStorageDisconnect", org.c_str());
			continue;
		} catch (svExStorageQuery &e) {
			svError("%s: svExStorageQuery", org.c_str());
			continue;
		} catch (svExStorageEscapeString &e) {
			svError("%s: svExStorageEscapeString", org.c_str());
			continue;
		} catch (svExStorageRecordNotFound &e) {
			svError("%s: svExStorageRecordNotFound", org.c_str());
			continue;
		} catch (svExStorageInvalidConf &e) {
			svError("%s: svExStorageInvalidConf", org.c_str());
			continue;
		} catch (svExStorageUnsupportedMethod &e) {
			svError("%s: svExStorageUsupportedMethod", org.c_str());
			continue;
		} catch (runtime_error &e) {
			//svError("%s: %s", org.c_str(), e.what());
			svError("%s: runtime_error", org.c_str());
			continue;
#endif
		} catch (svExStorageRecordNotFound &e) {
			svDebug("%s: %s", org.c_str(), e.what());
			continue;
		} catch (runtime_error &e) {
			svError("%s: %s", org.c_str(), e.what());
			continue;
		}

		break;
	}

	svEventServer::GetInstance()->Dispatch(
		new svEventHostKeyResult(this, NULL,
			request->GetDevice(), request->GetOrganization(), key));

	if (key.GetKey().size()) {
		if (key.HasExpired(hostkey_ttl)) {
			svDebug("%s: Using expired hostkey for: %s",
				org.c_str(), request->GetDevice().c_str());
			return;
		}

		for (vector<svStorageEngine *>::iterator i = engine.begin();
			i != engine.end(); i++) {
			if ((*i)->GetType() != svDT_BDB) continue;
			try {
				(*i)->CacheHostKey(request->GetDevice(), org, key);
			} catch (runtime_error &e) {
				svError("%s: %s", org.c_str(), e.what());
				continue;
			}
		}

		return;
	}

	svError("%s: Hostkey not found for: %s",
		org.c_str(), request->GetDevice().c_str());
}
Beispiel #18
0
void svServer::PoolClientSave(svEventPoolClientSave *event)
{
	svPoolClient *client = event->GetClient();
	svConfOrganization *org =
		conf->GetOrganization(client->GetOrganization());
	if (!org) {
		svError("%s: Organization not found: %s",
			name.c_str(), client->GetOrganization().c_str());
		delete client;
		return;
	}

	if (org->GetMaxPoolConnections() == 0) {
		svError("%s: %s: Pool connections disabled",
			name.c_str(), org->GetName().c_str());
		delete client;
		return;
	}

	map<string, map<string, vector<svPoolClient *> > >::iterator io;
	io = pool.find(client->GetOrganization());
	if (io != pool.end()) {
		map<string, vector<svPoolClient *> >::iterator id;
		id = io->second.find(client->GetDevice());
		if (id != io->second.end()) {
			if (id->second.size() >= org->GetMaxPoolConnections()) {
				svError("%s: %s: Maximum pool connections reached, "
					"clients: %d", name.c_str(),
					org->GetName().c_str(), skt_client.size());
				delete client;
				return;
			}
		}
	}

	svSocket *skt = client->GetSocket();
	skt->SetDevice(client->GetDevice());
	skt->SetOrganization(client->GetOrganization());
	skt->SetConnected();
	skt_client.push_back(skt);
	skt_set.SelectForRead(skt);

	pool[org->GetName()][client->GetDevice()].push_back(client);

	svLog("%s: Saved pool client: %s %s [%s] (%d)",
		name.c_str(), client->GetName().c_str(),
		client->GetDevice().c_str(), client->GetOrganization().c_str(),
		pool[org->GetName()][client->GetDevice()].size());

	map<string, svThreadStorage *>::iterator i;
	i = storage.find(client->GetOrganization());
	if (i != storage.end()) {
		svEventServer::GetInstance()->Dispatch(
			new svEventPoolClientUpdate(
				i->second, client->GetName(), client->GetDevice(),
				svPCS_IDLE));
	}

	for (io = pool.begin(); io != pool.end(); io++) {
		map<string, vector<svPoolClient *> >::iterator id;
		for (id = io->second.begin(); id != io->second.end(); id++) {
			vector<svPoolClient *>::iterator pci;
			for (pci = id->second.begin(); pci != id->second.end(); pci++) {
				svDebug("%s: Pool client: %s %s [%s]",
					name.c_str(), (*pci)->GetName().c_str(),
					(*pci)->GetDevice().c_str(), (*pci)->GetOrganization().c_str());
			}
		}
	}
}