int ACE_MEM_Addr::same_host (const ACE_INET_Addr &sap) { ACE_TRACE ("ACE_MEM_Addr::same_host"); // ACE_INET_Addr::operator== takes port number into account, so get // the addresses without a port number and compare. ACE_INET_Addr me (this->external_); ACE_INET_Addr you (sap); me.set_port_number (0); you.set_port_number (0); return me == you; }
int send_dgram (ACE_SOCK_Dgram &socket, ACE_INET_Addr addr, int done = 0) { // Send each message twice, once to the right port, and once to the "wrong" // port. This helps generate noise and lets us see if port filtering is // working properly. const char *address = addr.get_host_addr (); int port = addr.get_port_number (); for (int i = 0; i < 2; ++i) { char buf[MAX_STRING_SIZE]; if (done) buf[0] = 0; else ACE_OS::sprintf (buf, "%s/%d", address, port); if (socket.send (buf, ACE_OS::strlen (buf),addr) == -1) ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("Send to %C, %p\n"), address, ACE_TEXT ("send_dgram - error calling send on ") ACE_TEXT ("ACE_SOCK_Dgram.")), -1); addr.set_port_number (++port); } return 0; }
// static DeviceProxy * DeviceProxy::check_hello_and_create( ACE_Message_Block * mb , const ACE_INET_Addr& from_addr , Task * task ) { adportable::protocol::LifeCycleData data; adportable::protocol::LifeCycleFrame frame; if ( acewrapper::lifecycle_frame_serializer::unpack( mb, frame, data ) ) { try { using namespace adportable::protocol; LifeCycle_Hello& hello = boost::get< LifeCycle_Hello& >(data); ACE_INET_Addr addr; addr.string_to_addr( hello.ipaddr_.c_str() ); if ( addr.get_ip_address() == 0 ) { addr = from_addr; addr.set_port_number( hello.portnumber_ ); DeviceProxy * p = new DeviceProxy( addr, task ); p->initialize_dgram(); p->handle_lifecycle_mcast( frame, data ); #if defined _DEBUG // std::wstring key = adportable::string::convert( acewrapper::string( from_addr ) ); std::wstring text = adportable::string::convert( LifeCycleHelper::to_string( data ) ); task->dispatch_debug( text, p->name() ); #endif return p; // error should be handled by caller } } catch ( std::bad_cast& ) { } } return 0; }
int TAO::SSLIOP::Acceptor::open (TAO_ORB_Core *orb_core, ACE_Reactor *reactor, int major, int minor, const char *address, const char *options) { // Ensure that neither the endpoint configuration nor the ORB // configuration violate security measures. if (this->verify_secure_configuration (orb_core, major, minor) != 0) return -1; ACE_INET_Addr addr; ACE_CString specified_hostname; if (this->parse_address (address, addr, specified_hostname) == -1) return -1; // Open the non-SSL enabled endpoints, then open the SSL enabled // endpoints. if (this->IIOP_SSL_Acceptor::open (orb_core, reactor, major, minor, address, options) != 0) return -1; // The SSL port is set in the parse_options() method. All we have // to do is call open_i() addr.set_port_number (this->ssl_component_.port); return this->ssliop_open_i (orb_core, addr, reactor); }
// Realm List command handler bool AuthSocket::_HandleRealmList() { sLog->outDebug(LOG_FILTER_AUTHSERVER, "Entering _HandleRealmList"); if (socket().recv_len() < 5) return false; socket().recv_skip(5); // Get the user id (else close the connection) // No SQL injection (prepared statement) PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_ID_BY_NAME); stmt->setString(0, _login); PreparedQueryResult result = LoginDatabase.Query(stmt); if (!result) { sLog->outError(LOG_FILTER_AUTHSERVER, "'%s:%d' [ERROR] user %s tried to login but we cannot find him in the database.", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _login.c_str()); socket().shutdown(); return false; } Field* fields = result->Fetch(); uint32 id = fields[0].GetUInt32(); // Update realm list if need sRealmList->UpdateIfNeed(); ACE_INET_Addr clientAddr; socket().peer().get_remote_addr(clientAddr); // Circle through realms in the RealmList and construct the return packet (including # of user characters in each realm) ByteBuffer pkt; size_t RealmListSize = 0; for (RealmList::RealmMap::const_iterator i = sRealmList->begin(); i != sRealmList->end(); ++i) { // don't work with realms which not compatible with the client bool okBuild = ((_expversion & POST_BC_EXP_FLAG) && i->second.gamebuild == _build) || ((_expversion & PRE_BC_EXP_FLAG) && !AuthHelper::IsPreBCAcceptedClientBuild(i->second.gamebuild)); // No SQL injection. id of realm is controlled by the database. uint32 flag = i->second.flag; RealmBuildInfo const* buildInfo = AuthHelper::GetBuildInfo(i->second.gamebuild); if (!okBuild) { if (!buildInfo) continue; flag |= REALM_FLAG_OFFLINE | REALM_FLAG_SPECIFYBUILD; // tell the client what build the realm is for } if (!buildInfo) flag &= ~REALM_FLAG_SPECIFYBUILD; std::string name = i->first; if (_expversion & PRE_BC_EXP_FLAG && flag & REALM_FLAG_SPECIFYBUILD) { std::ostringstream ss; ss << name << " (" << buildInfo->MajorVersion << '.' << buildInfo->MinorVersion << '.' << buildInfo->BugfixVersion << ')'; name = ss.str(); } // We don't need the port number from which client connects with but the realm's port clientAddr.set_port_number(i->second.ExternalAddress.get_port_number()); uint8 lock = (i->second.allowedSecurityLevel > _accountSecurityLevel) ? 1 : 0; uint8 AmountOfCharacters = 0; stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_NUM_CHARS_ON_REALM); stmt->setUInt32(0, i->second.m_ID); stmt->setUInt32(1, id); result = LoginDatabase.Query(stmt); if (result) AmountOfCharacters = (*result)[0].GetUInt8(); pkt << i->second.icon; // realm type if (_expversion & POST_BC_EXP_FLAG) // only 2.x and 3.x clients pkt << lock; // if 1, then realm locked pkt << uint8(flag); // RealmFlags pkt << name; pkt << GetAddressString(GetAddressForClient(i->second, clientAddr)); pkt << i->second.populationLevel; pkt << AmountOfCharacters; pkt << i->second.timezone; // realm category if (_expversion & POST_BC_EXP_FLAG) // 2.x and 3.x clients pkt << uint8(0x2C); // unk, may be realm number/id? else pkt << uint8(0x0); // 1.12.1 and 1.12.2 clients if (_expversion & POST_BC_EXP_FLAG && flag & REALM_FLAG_SPECIFYBUILD) { pkt << uint8(buildInfo->MajorVersion); pkt << uint8(buildInfo->MinorVersion); pkt << uint8(buildInfo->BugfixVersion); pkt << uint16(buildInfo->Build); } ++RealmListSize; } if (_expversion & POST_BC_EXP_FLAG) // 2.x and 3.x clients { pkt << uint8(0x10); pkt << uint8(0x00); } else // 1.12.1 and 1.12.2 clients { pkt << uint8(0x00); pkt << uint8(0x02); } // make a ByteBuffer which stores the RealmList's size ByteBuffer RealmListSizeBuffer; RealmListSizeBuffer << uint32(0); if (_expversion & POST_BC_EXP_FLAG) // only 2.x and 3.x clients RealmListSizeBuffer << uint16(RealmListSize); else RealmListSizeBuffer << uint32(RealmListSize); ByteBuffer hdr; hdr << uint8(REALM_LIST); hdr << uint16(pkt.size() + RealmListSizeBuffer.size()); hdr.append(RealmListSizeBuffer); // append RealmList's size buffer hdr.append(pkt); // append realms in the realmlist socket().send((char const*)hdr.contents(), hdr.size()); return true; }
void AuthSocket::LoadRealmlist(ByteBuffer& pkt, uint32 acctid) { RealmList::RealmListIterators iters; iters = sRealmList.GetIteratorsForBuild(_build); uint32 numRealms = sRealmList.NumRealmsForBuild(_build); ACE_INET_Addr clientAddr; peer().get_remote_addr(clientAddr); switch (_build) { case 5875: // 1.12.1 case 6005: // 1.12.2 case 6141: // 1.12.3 { pkt << uint32(0); // unused value pkt << uint8(numRealms); for (RealmList::RealmStlList::const_iterator itr = iters.first; itr != iters.second; ++itr) { clientAddr.set_port_number((*itr)->ExternalAddress.get_port_number()); uint8 AmountOfCharacters; // No SQL injection. id of realm is controlled by the database. QueryResult* result = LoginDatabase.PQuery("SELECT numchars FROM realmcharacters WHERE realmid = '%d' AND acctid='%u'", (*itr)->m_ID, acctid); if (result) { Field* fields = result->Fetch(); AmountOfCharacters = fields[0].GetUInt8(); delete result; } else AmountOfCharacters = 0; bool ok_build = std::find((*itr)->realmbuilds.begin(), (*itr)->realmbuilds.end(), _build) != (*itr)->realmbuilds.end(); RealmBuildInfo const* buildInfo = ok_build ? FindBuildInfo(_build) : NULL; if (!buildInfo) buildInfo = &(*itr)->realmBuildInfo; RealmFlags realmflags = (*itr)->realmflags; // 1.x clients not support explicitly REALM_FLAG_SPECIFYBUILD, so manually form similar name as show in more recent clients std::string name = (*itr)->name; if (realmflags & REALM_FLAG_SPECIFYBUILD) { char buf[20]; snprintf(buf, 20, " (%u,%u,%u)", buildInfo->major_version, buildInfo->minor_version, buildInfo->bugfix_version); name += buf; } // Show offline state for unsupported client builds and locked realms (1.x clients not support locked state show) if (!ok_build || ((*itr)->allowedSecurityLevel > _accountSecurityLevel)) realmflags = RealmFlags(realmflags | REALM_FLAG_OFFLINE); pkt << uint32((*itr)->icon); // realm type pkt << uint8(realmflags); // realmflags pkt << name; // name pkt << GetAddressString(GetAddressForClient((**itr), clientAddr)); // address pkt << float((*itr)->populationLevel); pkt << uint8(AmountOfCharacters); pkt << uint8((*itr)->timezone); // realm category pkt << uint8(0x00); // unk, may be realm number/id? } pkt << uint16(0x0002); // unused value (why 2?) break; } case 8606: // 2.4.3 case 10505: // 3.2.2a case 11159: // 3.3.0a case 11403: // 3.3.2 case 11723: // 3.3.3a case 12340: // 3.3.5a case 13623: // 4.0.6a case 15050: // 4.3.0 case 15595: // 4.3.4 case 16357: // 5.1.0 case 16992: // 5.3.0 case 17055: // 5.3.0 case 17116: // 5.3.0 case 17128: // 5.3.0 case 17538: // 5.4.1 case 17658: // 5.4.2 case 17688: // 5.4.2a case 17898: // 5.4.7 case 17930: // 5.4.7 case 17956: // 5.4.7 case 18019: // 5.4.7 case 18291: // 5.4.8 case 18414: // 5.4.8 default: // and later { pkt << uint32(0); // unused value pkt << uint16(numRealms); for (RealmList::RealmStlList::const_iterator itr = iters.first; itr != iters.second; ++itr) { clientAddr.set_port_number((*itr)->ExternalAddress.get_port_number()); uint8 AmountOfCharacters; // No SQL injection. id of realm is controlled by the database. QueryResult* result = LoginDatabase.PQuery("SELECT numchars FROM realmcharacters WHERE realmid = '%d' AND acctid='%u'", (*itr)->m_ID, acctid); if (result) { Field* fields = result->Fetch(); AmountOfCharacters = fields[0].GetUInt8(); delete result; } else { AmountOfCharacters = 0; } bool ok_build = std::find((*itr)->realmbuilds.begin(), (*itr)->realmbuilds.end(), _build) != (*itr)->realmbuilds.end(); RealmBuildInfo const* buildInfo = ok_build ? FindBuildInfo(_build) : NULL; if (!buildInfo) { buildInfo = &(*itr)->realmBuildInfo; } uint8 lock = ((*itr)->allowedSecurityLevel > _accountSecurityLevel) ? 1 : 0; RealmFlags realmFlags = (*itr)->realmflags; // Show offline state for unsupported client builds if (!ok_build) { realmFlags = RealmFlags(realmFlags | REALM_FLAG_OFFLINE); } if (!buildInfo) { realmFlags = RealmFlags(realmFlags & ~REALM_FLAG_SPECIFYBUILD); } pkt << uint8((*itr)->icon); // realm type (this is second column in Cfg_Configs.dbc) pkt << uint8(lock); // flags, if 0x01, then realm locked pkt << uint8(realmFlags); // see enum RealmFlags pkt << (*itr)->name; // name pkt << GetAddressString(GetAddressForClient((**itr), clientAddr)); // address pkt << float((*itr)->populationLevel); pkt << uint8(AmountOfCharacters); pkt << uint8((*itr)->timezone); // realm category (Cfg_Categories.dbc) pkt << uint8(0x2C); // unk, may be realm number/id? if (realmFlags & REALM_FLAG_SPECIFYBUILD) { pkt << uint8(buildInfo->major_version); pkt << uint8(buildInfo->minor_version); pkt << uint8(buildInfo->bugfix_version); pkt << uint16(_build); } } pkt << uint16(0x0010); // unused value (why 10?) break; } } }
// service method int net_ace:: svc (void) { // NEW_THREAD net_ace runs as ACE_TASK _reactor = new ACE_Reactor; _acceptor = new net_ace_acceptor (this); ACE_INET_Addr addr (_port_self, getIPFromHost ()); printf ("net_ace::svc () default port: %d\n", _port_self); // obtain a valid server TCP listen port while (true) { // NEW_THREAD (ACE_DEBUG called for 1st time?) ACE_DEBUG ((LM_DEBUG, "(%5t) attempting to start server at %s:%d\n", addr.get_host_addr (), addr.get_port_number ())); if (_acceptor->open (addr, _reactor) == 0) break; _port_self++; addr.set_port_number (_port_self); } ACE_DEBUG ((LM_DEBUG, "net_ace::svc () called. actual port binded: %d\n", _port_self)); // create new handler for listening to UDP packets // NEW_THREAD will be created (new handler that will listen to port?) ACE_NEW_RETURN (_udphandler, net_ace_handler, -1); _udp = _udphandler->openUDP (addr); _udphandler->open (_reactor, this); // NOTE: this is a private IP, publicIP is obtained from server // register my own address _self_addr.setPublic ((uint32_t)addr.get_ip_address (), (uint16_t)addr.get_port_number ()); // self-determine preliminary hostID first _self_addr.host_id = this->resolveHostID (&_self_addr.publicIP); // wait a bit to avoid signalling before the main thread tries to wait ACE_Time_Value sleep_interval (0, 200000); ACE_OS::sleep (sleep_interval); // continue execution of original thread in open() _up_cond->signal (); // enter into event handling state while (_active) { _reactor->handle_events(); } ACE_DEBUG ((LM_DEBUG, "(%5t) net_ace::svc () leaving event handling loop\n")); _reactor->remove_handler (_acceptor, ACE_Event_Handler::DONT_CALL); // NOTE: _acceptor will be deleted when reactor is deleted as one of its // event handlers if (_reactor != NULL) { _reactor->close (); delete _reactor; _reactor = NULL; // NOTE: acceptor is self deleted when its handle_close () is called by reactor, // so no need to delete again here _acceptor = NULL; } // wait a bit to avoid signalling before the main thread tries to wait ACE_OS::sleep (sleep_interval); // continue execution of original thread in close() // to ensure that svc () will exit if (_down_cond != NULL) _down_cond->signal (); return 0; }