/** * @brief get name of socket type * * @param fd [in] socket fd * * @return socket type's name, if succ; NULL, if failed. */ char* get_socket_type_str(int fd) { int type = -1; int len = sizeof(type); int i = 0; struct socket_type sock_type[] = { MACRO_STR(SOCK_STREAM) , /* Sequenced, reliable, connection-based byte streams. */ MACRO_STR(SOCK_DGRAM) , /* Connectionless, unreliable datagrams of fixed maximum length. */ MACRO_STR(SOCK_RAW) , /* Raw protocol interface. */ MACRO_STR(SOCK_RDM) , /* Reliably-delivered messages. */ MACRO_STR(SOCK_SEQPACKET) , /* Sequenced, reliable, connection-based, datagrams of fixed maximum length. */ MACRO_STR(SOCK_PACKET) , /* Linux specific way of getting packets at the dev level. For writing rarp and other similar things on the user level. */ {-1, NULL} /* End */ }; if (getsockopt(fd, SOL_SOCKET, SO_TYPE, \ &type, (socklen_t *)&len)) { perror("getsockopt so_sndtimeo"); return NULL; } while (sock_type[i].type_name != NULL) { if (sock_type[i].type_macro == type) break; i++; } return sock_type[i].type_name; }
#include "socket_base.h" static struct socket_type sock_type[] = { MACRO_STR(SOCK_STREAM) , /* Sequenced, reliable, connection-based byte streams. */ MACRO_STR(SOCK_DGRAM) , /* Connectionless, unreliable datagrams of fixed maximum length. */ MACRO_STR(SOCK_RAW) , /* Raw protocol interface. */ MACRO_STR(SOCK_RDM) , /* Reliably-delivered messages. */ MACRO_STR(SOCK_SEQPACKET) , /* Sequenced, reliable, connection-based, datagrams of fixed maximum length. */ MACRO_STR(SOCK_PACKET) , /* Linux specific way of getting packets at the dev level. For writing rarp and other similar things on the user level. */ {-1, NULL} /* End */ }; /** * @brief printf socket error * * @param sc [in] string */ static void error_die(const char *sc) { perror(sc); exit(1); } /************************************************************* ********* Function Declaration Of Socket Basic ************* **************************************************************/ /** * @brief create a soocket * * @param domain [in] This value can be AF_INET,AF_UNIX,AF_LOCAL, * PF_INET, PF_UINX and PF_LOCAL.
void LogonServer::Run(int argc, char ** argv) { UNIXTIME = time(NULL); g_localTime = *localtime(&UNIXTIME); #ifdef WIN32 char * config_file = "ascnhalf-logonserver.conf"; #else char * config_file = new char[100]; sprintf(config_file, "%s", MACRO_STR(CONFDIR)); strcat(config_file, "/ascnhalf-logonserver.conf"); #endif int file_log_level = DEF_VALUE_NOT_SET; int screen_log_level = DEF_VALUE_NOT_SET; int do_check_conf = 0; int do_version = 0; struct option longopts[] = { { "checkconf", no_argument, &do_check_conf, 1 }, { "screenloglevel", required_argument, &screen_log_level, 1 }, { "fileloglevel", required_argument, &file_log_level, 1 }, { "version", no_argument, &do_version, 1 }, { "conf", required_argument, NULL, 'c' }, { 0, 0, 0, 0 } }; char c; while ((c = getopt_long_only(argc, argv, ":f:", longopts, NULL)) != -1) { switch (c) { case 'c': /* Log filename was set */ config_file = new char[strlen(ascnhalf_optarg)]; strcpy(config_file, ascnhalf_optarg); break; case 0: break; default: sLog.m_fileLogLevel = -1; sLog.m_screenLogLevel = 3; printf("Usage: %s [--checkconf] [--screenloglevel <level>] [--fileloglevel <level>] [--conf <filename>] [--version]\n", argv[0]); return; } } // Startup banner if(!do_version && !do_check_conf) { sLog.Init(-1, 3); } else { sLog.m_fileLogLevel = -1; sLog.m_screenLogLevel = 3; } sLog.outString(BANNER, BUILD_HASH, CONFIG, PLATFORM_TEXT, ARCH); //printf("Built at %s on %s by %s@%s\n", BUILD_TIME, BUILD_DATE, BUILD_USER, BUILD_HOST); sLog.outString("=============================================================================="); sLog.outString(""); if(do_version) return; if(do_check_conf) { printf("Checking config file: %s\n", config_file); if(Config.MainConfig.SetSource(config_file, true)) { printf(" Passed without errors.\n"); } else { printf(" Encountered one or more errors.\n"); } /* test for die variables */ string die; if(Config.MainConfig.GetString("die", "msg", &die) || Config.MainConfig.GetString("die2", "msg", &die)) { printf("Die directive received: %s", die.c_str()); } return; } sLog.outString("The key combination <Ctrl-C> will safely shut down the server at any time."); sLog.outString(""); Log.Notice("System","Initializing Random Number Generators..."); Log.Notice("Config", "Loading Config Files..."); if(!Rehash()) { return; } Log.Notice("ThreadMgr", "Starting..."); ThreadPool.Startup(); if(!startdb()) { return; } Log.Notice("AccountMgr", "Starting..."); new AccountMgr; new IPBanner; Log.Notice("InfoCore", "Starting..."); new InformationCore; new PatchMgr; Log.Notice("AccountMgr", "Precaching accounts..."); sAccountMgr.ReloadAccounts(true); Log.Notice("AccountMgr", "%u accounts are loaded and ready.", sAccountMgr.GetCount()); Log.Line(); // Spawn periodic function caller thread for account reload every 10mins int atime = Config.MainConfig.GetIntDefault("Rates", "AccountRefresh",600); atime *= 1000; PeriodicFunctionCaller<AccountMgr> * pfc = new PeriodicFunctionCaller<AccountMgr>(AccountMgr::getSingletonPtr(),&AccountMgr::ReloadAccountsCallback, atime); ThreadPool.ExecuteTask(pfc); // Load conf settings.. uint32 cport = Config.MainConfig.GetIntDefault("Listen", "RealmListPort", 3724); uint32 sport = Config.MainConfig.GetIntDefault("Listen", "ServerPort", 8093); string host = Config.MainConfig.GetStringDefault("Listen", "Host", "0.0.0.0"); string shost = Config.MainConfig.GetStringDefault("Listen", "ISHost", host.c_str()); min_build = Config.MainConfig.GetIntDefault("Client", "MinBuild", 6180); max_build = Config.MainConfig.GetIntDefault("Client", "MaxBuild", 6999); string logon_pass = Config.MainConfig.GetStringDefault("LogonServer", "RemotePassword", "r3m0t3b4d"); Sha1Hash hash; hash.UpdateData(logon_pass); hash.Finalize(); memcpy(sql_hash, hash.GetDigest(), 20); ThreadPool.ExecuteTask(new LogonConsoleThread); new SocketMgr; new SocketGarbageCollector; sSocketMgr.SpawnWorkerThreads(); ListenSocket<AuthSocket> * cl = new ListenSocket<AuthSocket>(host.c_str(), cport); ListenSocket<LogonCommServerSocket> * sl = new ListenSocket<LogonCommServerSocket>(shost.c_str(), sport); // Spawn auth listener // Spawn interserver listener bool authsockcreated = cl->IsOpen(); bool intersockcreated = sl->IsOpen(); #ifdef WIN32 if(authsockcreated) { ThreadPool.ExecuteTask(cl); } if(intersockcreated) { ThreadPool.ExecuteTask(sl); } #endif // hook signals Log.Notice("LogonServer","Hooking signals..."); signal(SIGINT, _OnSignal); signal(SIGTERM, _OnSignal); signal(SIGABRT, _OnSignal); #ifdef _WIN32 signal(SIGBREAK, _OnSignal); #else signal(SIGHUP, _OnSignal); #endif /* write pid file */ FILE * fPid = fopen("logonserver.pid", "w"); if(fPid) { uint32 pid; #ifdef WIN32 pid = GetCurrentProcessId(); #else pid = getpid(); #endif fprintf(fPid, "%u", (unsigned int)pid); fclose(fPid); } uint32 loop_counter = 0; //ThreadPool.Gobble(); Log.Notice("LogonServer","Success! Ready for connections"); while(mrunning && authsockcreated && intersockcreated) { if(!(++loop_counter % 10000)) // 2mins { ThreadPool.IntegrityCheck(2); //Logonserver don't need as many threads as world-server, 2 will do } if(!(loop_counter % 100)) //100 loop ~ 1seconds { sInfoCore.TimeoutSockets(); sSocketGarbageCollector.Update(); CheckForDeadSockets(); // Flood Protection UNIXTIME = time(NULL); g_localTime = *localtime(&UNIXTIME); } PatchMgr::getSingleton().UpdateJobs(); Sleep(10); } Log.Notice("LogonServer","Shutting down..."); signal(SIGINT, 0); signal(SIGTERM, 0); signal(SIGABRT, 0); #ifdef _WIN32 signal(SIGBREAK, 0); #else signal(SIGHUP, 0); #endif pfc->kill(); cl->Close(); sl->Close(); sSocketMgr.CloseAll(); #ifdef WIN32 sSocketMgr.ShutdownThreads(); #endif sLogonConsole.Kill(); delete LogonConsole::getSingletonPtr(); // kill db sLog.outString("Waiting for database to close.."); sLogonSQL->EndThreads(); sLogonSQL->Shutdown(); delete sLogonSQL; ThreadPool.Shutdown(); // delete pid file remove("logonserver.pid"); delete AccountMgr::getSingletonPtr(); delete InformationCore::getSingletonPtr(); delete IPBanner::getSingletonPtr(); delete SocketMgr::getSingletonPtr(); delete SocketGarbageCollector::getSingletonPtr(); delete pfc; printf("Shutdown complete.\n"); }
int Application::run() { std::cout << "***********************************************************" << std::endl << "* ON Server v" << MACRO_STR(DETECTED_ON_VERSION) << " (built on " << MACRO_STR(BUILD_DATE) << ")" << std::endl << "* (c) Copyright 2009 - " << MACRO_STR(BUILD_YEAR) << " IWStudio" << std::endl << "* Released under GNU General Public License, vesion 2" << std::endl << "*" << std::endl << std::endl; _INFO(_logModule, "ON Server Starting Up..."); setApplicationName("ONCoreServer"); setApplicationVersion(MACRO_STR(DETECTED_ON_VERSION)); setOrganizationName("IWStudio"); setOrganizationDomain("iwstudio.hu"); _INFO(_logModule, "Installing signal handlers"); connect(new Common::UnixSignalHandler(SIGHUP, this), SIGNAL(CoughtSignal()), SLOT(quit())); connect(new Common::UnixSignalHandler(SIGINT, this), SIGNAL(CoughtSignal()), SLOT(quit())); connect(new Common::UnixSignalHandler(SIGQUIT, this), SIGNAL(CoughtSignal()), SLOT(quit())); connect(new Common::UnixSignalHandler(SIGTERM, this), SIGNAL(CoughtSignal()), SLOT(quit())); _INFO(_logModule, "Parsing commandline arguments"); _INFO(_logModule, "Loading config file"); _INFO(_logModule, "Setting up logger"); Common::Logger::Instance()->SetLogToStdout(true); Common::Logger::Instance()->SetStdoutLogLevel(Common::Logger::Level::Trace); Common::Logger::Instance()->SetFileLogLevel(Common::Logger::Level::Trace); Common::Logger::Instance()->SetLogFormat(Common::Logger::Format::Csv); Common::Logger::Instance()->SetLogFile(QString(getenv("HOME")).append("/ONServerCore.log")); Common::Logger::Instance()->FlushStartupBuffer(); _INFO(_logModule, "Setting up command interface"); ServerCore::CommandInterface commander; connect(&commander, SIGNAL(Quit()), SLOT(quit())); _INFO(_logModule, "Starting Readline"); ServerCore::Readline readline("on> "); readline.connect(Common::Logger::Instance().data(), SIGNAL(BeforeLogLine()), SLOT(Disable()), Qt::DirectConnection); readline.connect(Common::Logger::Instance().data(), SIGNAL(AfterLogLine()), SLOT(Enable()), Qt::DirectConnection); connect(&readline, SIGNAL(EndSignal()), SLOT(quit())); commander.connect(&readline, SIGNAL(LineRead(QString)), SLOT(ProcessCommand(QString))); _INFO(_logModule, "Start listening"); ServerCore::Listener listener; listener.listen(3214); _INFO(_logModule, "ON Server Startup Complete"); int exitCode = QCoreApplication::exec(); _INFO(_logModule, "ON Server Shutting Down..."); Common::Logger::Instance()->disconnect(&readline); readline.Disable(); return exitCode; }