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; } }
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; } }
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); }
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; }
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; } } }
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(); }
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; } }
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; } }
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]); }
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()); } } }
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); }
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; }
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 }
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 }
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)); }
static void db_panic(DB_ENV *db_env, int errval) { svError("db: panic: %s", db_strerror(errval)); }
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()); }
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()); } } } }