void Battlenet::Session::CheckIpCallback(PreparedQueryResult result) { if (result) { bool banned = false; do { Field* fields = result->Fetch(); if (fields[0].GetUInt64() != 0) banned = true; if (!fields[1].GetString().empty()) _ipCountry = fields[1].GetString(); } while (result->NextRow()); if (banned) { Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); logonResponse->SetAuthResult(AUTH_INTERNAL_ERROR); AsyncWrite(logonResponse); TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Banned ip '%s:%d' tries to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort()); return; } } AsyncRead(); }
VOID WINAPI CompletedWriteRoutine( DWORD err, DWORD written, LPOVERLAPPED overlap) { auto context = (Connection::IoCompletionRoutine*)overlap; auto self = context->self; if (err == ERROR_OPERATION_ABORTED) { SetEvent(self->cancel_io_event_.get()); assert(("write operation should not be cancelled", false)); return; } bool io = false; // The write operation has finished, so read() the next request (if // there is no error) or continue write if necessary. if ((err == 0) && (written == self->write_size_)) { bool pendding = false; std::string message; { std::unique_lock<std::mutex> lock(self->sending_queue_mutex_); pendding = !self->sending_queue_.empty(); if (pendding) { message = self->sending_queue_.front(); self->sending_queue_.pop_front(); self->state_ = Connection::SEND_PENDDING; } else { self->state_ = Connection::CONNECTED; } } io = pendding ? self->AsyncWrite(message, CompletedWriteRoutine) : self->AsyncRead(CompletedReadRoutine); } if (!io) { self->Shutdown(); } }
void CSapConnection::HandleConnected(const boost::system::error_code& err,tcp::resolver::iterator endpoint_iterator) { SS_XLOG(XLOG_DEBUG,"CSapConnection::%s,id[%d]\n",__FUNCTION__,m_nId); if (!err) { gettimeofday_a(&m_HeartBeatPoint,NULL); gettimeofday_a(&m_AlivePoint,NULL); ConnectFinish(0); m_isConnected=true; SetRemoteAddr(); AsyncRead(); } else if (endpoint_iterator != tcp::resolver::iterator()) { boost::system::error_code ignore_ec; m_socket.close(ignore_ec); tcp::endpoint endpoint = *endpoint_iterator; m_socket.async_connect(endpoint, MakeSapAllocHandler(m_allocReader,boost::bind(&CSapConnection::HandleConnected, shared_from_this(), boost::asio::placeholders::error, ++endpoint_iterator))); } else { //SS_SLOG(XLOG_WARNING,"CSapConnection::"<<__FUNCTION__<<",id["<<m_nId<<"],addr[], error:" <<err.message()<<"\n"); SS_XLOG(XLOG_WARNING,"CSapConnection::%s, id[%d], error:%s\n", __FUNCTION__,m_nId,(err.message()).c_str()); ConnectFinish(-3); } }
void InterConnection::onRead(const boost::system::error_code &e, std::size_t bytesTransferred) { // Read the incoming buffer and parse the packet if (!e && bytesTransferred >= 8) { uint32 pSize = 0; m_readBuffer >> pSize; if (pSize == bytesTransferred) // valid size { uint32 opcode = 0; m_readBuffer >> opcode; switch (opcode) { case 0x01: onRequestAuth(); break; case 0x02: onRegisterCharServer(); break; default: Logger::log("Unknown opcode %d\n",opcode); return; } m_readBuffer.reset(); AsyncRead(); return; }
void TransportTCPWriter::OnRead() { Log_Trace("endpoint = %s", endpoint.ToString()); // drop any data readBuffer.Clear(); AsyncRead(); }
void TransportTCPWriter::OnConnect() { TCPConn<>::OnConnect(); Log_Trace("endpoint = %s", endpoint.ToString()); AsyncRead(); }
void CatchupReader::OnConnect() { Log_Trace(); TCPConn<>::OnConnect(); AsyncRead(); }
void LinuxInputDevice::OnReadReady(const boost::system::error_code &ec) { if (ec) return; Read(); if (fd.is_open()) AsyncRead(); }
void Battlenet::Session::HandshakeHandler(boost::system::error_code const& error) { if (error) { TC_LOG_ERROR("session", "%s SSL Handshake failed %s", GetClientInfo().c_str(), error.message().c_str()); CloseSocket(); return; } AsyncRead(); }
void Socket::ReadHandler() { if (!IsOpen()) return; MessageBuffer& packet = GetReadBuffer(); while (packet.GetActiveSize() > 0) { if (_headerBuffer.GetRemainingSpace() > 0) { // need to receive the header std::size_t readHeaderSize = std::min(packet.GetActiveSize(), _headerBuffer.GetRemainingSpace()); _headerBuffer.Write(packet.GetReadPointer(), readHeaderSize); packet.ReadCompleted(readHeaderSize); if (_headerBuffer.GetRemainingSpace() > 0) break; // We just received nice new header if (!ReadHeaderHandler()) { CloseSocket(); return; } } // We have full read header, now check the data payload if (_packetBuffer.GetRemainingSpace() > 0) { // need more data in the payload std::size_t readDataSize = std::min(packet.GetActiveSize(), _packetBuffer.GetRemainingSpace()); _packetBuffer.Write(packet.GetReadPointer(), readDataSize); packet.ReadCompleted(readDataSize); if (_packetBuffer.GetRemainingSpace() > 0) { // Couldn't receive the whole data this time. break; } } // just received fresh new payload if (!ReadDataHandler()) { CloseSocket(); _headerBuffer.Reset(); return; } _headerBuffer.Reset(); } AsyncRead(); }
void Battlenet::Session::ReadHandler() { BitStream stream(std::move(GetReadBuffer())); _crypt.DecryptRecv(stream.GetBuffer(), stream.GetSize()); while (!stream.IsRead()) { try { PacketHeader header; header.Opcode = stream.Read<uint32>(6); if (stream.Read<bool>(1)) header.Channel = stream.Read<int32>(4); if (header.Channel != AUTHENTICATION && (header.Channel != CONNECTION || header.Opcode != Connection::CMSG_PING) && !_authed) { TC_LOG_DEBUG("session.packets", "%s Received not allowed %s. Client has not authed yet.", GetClientInfo().c_str(), header.ToString().c_str()); CloseSocket(); return; } if (ClientPacket* packet = sPacketManager.CreateClientPacket(header, stream)) { if (sPacketManager.IsHandled(header)) TC_LOG_DEBUG("session.packets", "%s Received %s", GetClientInfo().c_str(), PacketToStringHelper(packet).c_str()); packet->CallHandler(this); delete packet; } else if (sPacketManager.GetClientPacketName(header)) { LogUnhandledPacket(header); break; } else { TC_LOG_DEBUG("session.packets", "%s Received unknown %s", GetClientInfo().c_str(), header.ToString().c_str()); break; } stream.AlignToNextByte(); } catch (BitStreamPositionException const& e) { TC_LOG_ERROR("session.packets", "%s Exception thrown during packet processing %s", GetClientInfo().c_str(), e.what()); CloseSocket(); return; } } GetReadBuffer().Resize(size_t(BufferSizes::Read)); AsyncRead(); }
void TCPConnection::ProcessOperationQueue_(int recurse_level) { if (recurse_level > 10) { throw std::logic_error(Formatter::FormatAsAnsi("Recurse level {0} was reached in TCPConnection::ProcessOperationQueue_ for session {1}", recurse_level, session_id_)); } // Pick out the next item to process... std::shared_ptr<IOOperation> operation = operation_queue_.Front(); if (!operation) { // We're no longer sending... return; } switch (operation->GetType()) { case IOOperation::BCTHandshake: { AsyncHandshake(); break; } case IOOperation::BCTWrite: { std::shared_ptr<ByteBuffer> pBuf = operation->GetBuffer(); AsyncWrite(pBuf); break; } case IOOperation::BCTRead: { AsyncRead(operation->GetString()); break; } case IOOperation::BCTShutdownSend: { Shutdown(boost::asio::ip::tcp::socket::shutdown_send); operation_queue_.Pop(IOOperation::BCTShutdownSend); ProcessOperationQueue_(recurse_level + 1); break; } case IOOperation::BCTDisconnect: { Disconnect(); operation_queue_.Pop(IOOperation::BCTDisconnect); ProcessOperationQueue_(recurse_level + 1); break; } } }
cf_void OnAcceptComplete(cf::T_SESSION session) { CF_PRINT_FUNC; #if 1 fprintf (stderr, "OnAcceptComplete,fd=%d,addr=%s \n", session->Fd(),session->Addr().c_str()); #endif if(session->Addr()=="127.0.0.1") { TYPE_TID_CLIENTFD::iterator it =g_tid_fd.begin(); bool found =false; cf_uint32 tid =0; for(;it!=g_tid_fd.end();it++) { if(it->second==-1) { tid =it->first; found =true; break; } } if(found) { printf( "g_tid_fd.size()=%u,g_tid_fd[%u]=%d \n", (cf_uint32)(g_tid_fd.size()), tid,g_tid_fd[tid]); g_tid_fd[tid] =session->Fd(); g_tid_fd[tid] =1234; printf( "g_tid_fd[%u]=%u , g_tid_fd.size()=%u \n",(cf_uint32)tid,(cf_uint32)(g_tid_fd[tid]), (cf_uint32)(g_tid_fd.size()) ); AsyncRead(session->Fd(), 1); } else printf("ERROR! Idle element in g_tid_fd not found!"); return; } AsyncRead(session->Fd(), _headLen); _recvHeader[session->Fd()] =true; }
Connection::Connection( const std::string& name, HANDLE pipe, HANDLE post_event, HANDLE send_event) : name_(name), state_(UNKNOW), pipe_(pipe), post_event_(post_event), send_event_(send_event), cancel_io_event_(CreateEvent(NULL, FALSE, FALSE, NULL)), write_size_(0), io_thread_id_(std::this_thread::get_id()), disconnecting_(false) { ZeroMemory(read_buf_, sizeof read_buf_); ZeroMemory(write_buf_, sizeof write_buf_); ZeroMemory(&io_overlap_, sizeof io_overlap_); io_overlap_.self = this; AsyncRead(CompletedReadRoutine); }
void CNetwork::OnConnect(const boost::system::error_code &error_code) { if (error_code.value() == 0) { m_Connected = true; Execute(fmt::format("use port={}", m_ServerPort)); AsyncRead(); //start heartbeat check NetAlive(boost::system::error_code(), false); } else { CCallbackHandler::Get()->ForwardError( EErrorType::CONNECTION_ERROR, error_code.value(), fmt::format("error while connecting to server: {}", error_code.message())); } }
VOID WINAPI CompletedWriteRoutineForWait( DWORD err, DWORD written, LPOVERLAPPED overlap) { auto context = (Connection::IoCompletionRoutine*)overlap; auto self = context->self; if (err == ERROR_OPERATION_ABORTED) { SetEvent(self->cancel_io_event_.get()); assert(("write operation should not be cancelled", false)); return; } bool io = false; // The write operation has finished, so read() the next request (if // there is no error) or continue write if necessary. if ((err == 0) && (written == self->write_size_)) { io = self->AsyncRead(CompletedReadRoutineForWait); } if (!io) { self->Shutdown(); } }
void TCPPort::OnRead(const boost::system::error_code &ec, size_t nbytes) { if (ec == boost::asio::error::operation_aborted) /* this object has already been deleted; bail out quickly without touching anything */ return; if (ec) { connection.close(); AsyncAccept(); StateChanged(); Error(ec.message().c_str()); return; } DataReceived(input, nbytes); AsyncRead(); }
void TCPPort::OnAccept(const boost::system::error_code &ec) { if (ec == boost::asio::error::operation_aborted) /* this object has already been deleted; bail out quickly without touching anything */ return; if (ec) { acceptor.close(); StateChanged(); Error(ec.message().c_str()); return; } StateChanged(); connection.set_option(SendTimeoutS(1)); AsyncRead(); }
bool LinuxInputDevice::Open(const char *path) { FileDescriptor _fd; if (!_fd.OpenReadOnly(path)) return false; _fd.SetNonBlocking(); fd.assign(_fd.Get()); AsyncRead(); min_x = max_x = min_y = max_y = 0; is_pointer = IsPointerDevice(fd.native_handle()); if (is_pointer) { merge.AddPointer(); if (!IsKobo()) { /* obtain touch screen information */ /* no need to do that on the Kobo, because we know its touch screen is well-calibrated */ input_absinfo abs; if (ioctl(fd.native_handle(), EVIOCGABS(ABS_X), &abs) == 0) { min_x = abs.minimum; max_x = abs.maximum; } if (ioctl(fd.native_handle(), EVIOCGABS(ABS_Y), &abs) == 0) { min_y = abs.minimum; max_y = abs.maximum; } } } rel_x = rel_y = rel_wheel = 0; down = false; moving = pressing = releasing = false; return true; }
VOID WINAPI CompletedReadRoutineForWait( DWORD err, DWORD readed, LPOVERLAPPED overlap) { auto context = (Connection::IoCompletionRoutine*)overlap; auto self = context->self; if (err == ERROR_OPERATION_ABORTED) { SetEvent(self->cancel_io_event_.get()); return; } bool io = false; if ((err == 0) && (readed != 0)) { auto message = std::string(self->read_buf_, readed); std::unique_lock<std::mutex> lock(self->transact_message_buffer_mutex_); message.swap(self->transact_message_buffer_); self->transact_message_buffer_cond.notify_all(); io = self->AsyncRead(CompletedReadRoutine); } if (!io) { self->Shutdown(); } }
VOID WINAPI CompletedReadRoutine( DWORD err, DWORD readed, LPOVERLAPPED overlap) { auto context = (Connection::IoCompletionRoutine*)overlap; auto self = context->self; if (err == ERROR_OPERATION_ABORTED) { SetEvent(self->cancel_io_event_.get()); return; } bool io = false; if ((err == 0) && (readed != 0)) { auto message = std::string(self->read_buf_, readed); io = self->AsyncRead(CompletedReadRoutine); if (!message.empty()) { self->message_callback_(self->shared_from_this(), message); } } if (!io) { self->Shutdown(); } }
void Battlenet::Session::ReadHandler() { if (!IsOpen()) return; MessageBuffer& packet = GetReadBuffer(); while (packet.GetActiveSize() > 0) { if (!PartialProcessPacket<&Battlenet::Session::ReadHeaderLengthHandler, &Battlenet::Session::_headerLengthBuffer>(this, packet)) break; if (!PartialProcessPacket<&Battlenet::Session::ReadHeaderHandler, &Battlenet::Session::_headerBuffer>(this, packet)) break; if (!PartialProcessPacket<&Battlenet::Session::ReadDataHandler, &Battlenet::Session::_packetBuffer>(this, packet)) break; _headerLengthBuffer.Reset(); _headerBuffer.Reset(); } AsyncRead(); }
/* - result data is sent as a string which ends with "\n\r" - the Teamspeak3 server can send multiple strings - the end of a result set is always an error result string */ void CNetwork::OnRead(const boost::system::error_code &error_code) { if (error_code.value() == 0) { static vector<string> captured_data; std::istream tmp_stream(&m_ReadStreamBuf); string read_data; std::getline(tmp_stream, read_data, '\r'); #ifdef _DEBUG string dbg_read_data(read_data); bool first_line = true; do { logprintf("%s> %s", first_line == true ? ">>>" : " ", dbg_read_data.substr(0, 512).c_str()); dbg_read_data.erase(0, 512); first_line = false; } while (dbg_read_data.empty() == false); #endif //regex: parse error //if this is an error message, it means that no other result data will come static const boost::regex error_rx("error id=([0-9]+) msg=([^ \n]+)"); boost::smatch error_rx_result; if (boost::regex_search(read_data, error_rx_result, error_rx)) { if (error_rx_result[1].str() == "0") { for (auto i = captured_data.begin(); i != captured_data.end(); ++i) { string &data = *i; if (data.find('|') == string::npos) continue; //we have multiple data rows with '|' as delimiter here, //split them up and re-insert every single row vector<string> result_set; size_t delim_pos = 0; do { size_t old_delim_pos = delim_pos; delim_pos = data.find('|', delim_pos); string row = data.substr(old_delim_pos, delim_pos - old_delim_pos); result_set.push_back(row); } while (delim_pos != string::npos && ++delim_pos); i = captured_data.erase(i); for (auto j = result_set.begin(), jend = result_set.end(); j != jend; ++j) i = captured_data.insert(i, *j); } //call callback and send next command m_CmdQueueMutex.lock(); if (m_CmdQueue.empty() == false) { ReadCallback_t &callback = m_CmdQueue.front().get<1>(); if (callback) { m_CmdQueueMutex.unlock(); callback(captured_data); //calls the callback m_CmdQueueMutex.lock(); } m_CmdQueue.pop(); if (m_CmdQueue.empty() == false) AsyncWrite(m_CmdQueue.front().get<0>()); } m_CmdQueueMutex.unlock(); } else { string error_str(error_rx_result[2].str()); unsigned int error_id = 0; CUtils::Get()->UnEscapeString(error_str); CUtils::Get()->ConvertStringToInt(error_rx_result[1].str(), error_id); m_CmdQueueMutex.lock(); CCallbackHandler::Get()->ForwardError( EErrorType::TEAMSPEAK_ERROR, error_id, fmt::format("error while executing \"{}\": {}", m_CmdQueue.front().get<0>(), error_str)); m_CmdQueue.pop(); if (m_CmdQueue.empty() == false) AsyncWrite(m_CmdQueue.front().get<0>()); m_CmdQueueMutex.unlock(); } captured_data.clear(); } else if (read_data.find("notify") == 0) { //check if notify is duplicate static string last_notify_data; static const vector<string> duplicate_notifies{ "notifyclientmoved", "notifycliententerview", "notifyclientleftview" }; bool is_duplicate = false; for (auto &s : duplicate_notifies) { if (read_data.find(s) == 0) { if (last_notify_data == read_data) is_duplicate = true; break; } } if (is_duplicate == false) { //notify event boost::smatch event_result; for (auto &event : m_EventList) { if (boost::regex_search(read_data, event_result, event.get<0>())) { event.get<1>()(event_result); break; } } } last_notify_data = read_data; } else { //stack the result data if it is not an error or notification message captured_data.push_back(read_data); } AsyncRead(); } else //error { CCallbackHandler::Get()->ForwardError( EErrorType::CONNECTION_ERROR, error_code.value(), fmt::format("error while reading: {}", error_code.message())); //"disable" the plugin, since calling Disconnect() or //destroying CNetwork here is not very smart CServer::CSingleton::Destroy(); m_Connected = false; //we're not _really_ connected, are we? } }
void Socket::Start() { AsyncRead(); }
void InterConnection::start() { AsyncRead(); Logger::log("New connection from char server\n"); }
cf_void OnReadComplete(cf::T_SESSION session, std::shared_ptr < cl::ReadBuffer > readBuffer) { CF_PRINT_FUNC; #if 1 fprintf (stderr, "OnReadComplete,fd=%d,addr=%s,total()=%d,buf=%s \n", session->Fd(),session->Addr().c_str(),readBuffer->GetTotal(), (cf_char *)(readBuffer->GetBuffer())); #endif TYPE_TID_CLIENTFD::const_iterator it =g_tid_fd.begin(); bool found =false; for(;it!=g_tid_fd.end();it++) { printf( "for,tid=%u,fd=%d g_tid_fd.size()=%u\n",(cf_uint32)(it->first),it->second, (cf_uint32)(g_tid_fd.size()) ); if(it->second==session->Fd()) { found =true; break; } } if(found) { printf( "is db query. \n" ); QueueElement qeOut =g_outQueue[_tid].Get(); int clientfd =qeOut.fd; std::string output_data =qeOut.pack; AsyncWrite(clientfd, output_data.c_str(), output_data.size()); return; } printf( "recv query request \n" ); cf_uint32 totalLen =readBuffer->GetTotal(); if(_recvHeader[session->Fd()]) { if(_headLen!=totalLen) { fprintf (stderr, "OnReadComplete,fd=%d,_headLen{%u}!=totalLen{%u} \n", session->Fd(),_headLen,totalLen); } else { cf_uint32 * p =(cf_uint32 *)(readBuffer->GetBuffer()); cf_uint32 size =ntohl(*p); _recvHeader[session->Fd()] =false; if(size>0) AsyncRead(session->Fd(), size); else _THROW(cf::ValueError, "size==0 !"); } } else { _recvHeader[session->Fd()] =true; //AsyncWrite(session->Fd(), readBuffer->GetBuffer(), totalLen); std::string packet((const char*)(readBuffer->GetBuffer()), size_t(totalLen)); QueueElement qe; qe.fd =session->Fd(); qe.pack =packet; g_inQueue[g_tid_pipe[_tid]].Put(qe); AsyncRead(session->Fd(), _headLen); } }
void Battlenet::Session::Start() { TC_LOG_TRACE("session", "Accepted connection from %s", GetRemoteIpAddress().to_string().c_str()); AsyncRead(); }
void MessageConnection::OnConnect() { TCPConnection::OnConnect(); AsyncRead(); }