double fix_EM(const int nbr_cls_st, vector<coordonnees_c> &Cfinal, coordonnees_p *p, bool postK = false){ double L, Ltmp, Lfinal; bool first = true; vector<coordonnees_c> C(nbr_cls_st); vector<coordonnees_c> Ctmp(nbr_cls_st); for(unsigned t=0; t<10; t++){ bool start =false; if(!postK){ while(!start){ genrdm(C, nbr_cls_st); closest_c(p, C, nbr_cls_st); start = init_covar(nbr_cls_st, C, p); } }else{ start = init_covar(nbr_cls_st, Cfinal, p); C = Cfinal; if(!start){ //cout << "AIC_K start initialization didn't work." << endl << "Jump to normal EM" << endl; postK =false; while(!start){ genrdm(C, nbr_cls_st); closest_c(p, C, nbr_cls_st); start = init_covar(nbr_cls_st, C, p); } } } L = log_l(nbr_cls_st, C, p); Lfinal = L; bool L_smaller = true; Ctmp = C; int n=0; while(L_smaller){ L_smaller = false; resp(nbr_cls_st, Ctmp, p); mean_EM(nbr_cls_st, Ctmp, p); covar_EM(nbr_cls_st, Ctmp, p); Ltmp = log_l(nbr_cls_st, Ctmp, p); if(Ltmp > L){ n++; L_smaller = true; L = Ltmp; C = Ctmp; } } if((first == true && !postK) || (L > Lfinal)){ first = false; Lfinal = L; Cfinal = C; } if(postK){ //cout << "Iteration : " << n << endl; break; } } return Lfinal; }
void CAimProto::aim_connection_clientlogin(void) { pass_ptrA password(getStringA(AIM_KEY_PW)); replaceStr(m_username, ptrA(getStringA(AIM_KEY_SN))); CMStringA buf; buf.Format("devId=%s&f=xml&pwd=%s&s=%s", AIM_DEFAULT_CLIENT_KEY, ptrA(mir_urlEncode(password)), ptrA(mir_urlEncode(m_username))); NETLIBHTTPHEADER headers[] = { { "Content-Type", "application/x-www-form-urlencoded; charset=UTF-8" } }; NETLIBHTTPREQUEST req = { 0 }; req.cbSize = sizeof(req); req.flags = NLHRF_SSL; req.requestType = REQUEST_POST; req.szUrl = AIM_LOGIN_URL; req.headers = headers; req.headersCount = _countof(headers); req.pData = buf.GetBuffer(); req.dataLength = buf.GetLength(); NLHR_PTR resp(CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)m_hNetlibUser, (LPARAM)&req)); if (!resp || !resp->dataLength) { broadcast_status(ID_STATUS_OFFLINE); return; } time_t hosttime; CMStringA token, secret; if (!parse_clientlogin_response(resp, headers, token, secret, hosttime)) { //TODO: handle error broadcast_status(ID_STATUS_OFFLINE); mir_free(headers[0].szValue); return; } bool encryption = !getByte(AIM_KEY_DSSL, 0); CMStringA url; fill_session_url(url, token, secret, hosttime, password, encryption); // reuse NETLIBHTTPREQUEST req.requestType = REQUEST_GET; req.pData = NULL; req.flags |= NLHRF_MANUALHOST; req.dataLength = 0; req.headersCount = 1; req.szUrl = url.GetBuffer(); { NETLIBHTTPHEADER headers2[] = { { "Host", "api.oscar.aol.com" }, }; req.headers = headers2; resp = CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)m_hNetlibUser, (LPARAM)&req); } if (!resp || !resp->dataLength) { // TODO: handle error broadcast_status(ID_STATUS_OFFLINE); return; } CMStringA bos_host, cookie, tls_cert_name; //TODO: find efficient buf size unsigned short bos_port = 0; if (!parse_start_socar_session_response(resp->pData, bos_host, bos_port, cookie, tls_cert_name, encryption)) { // TODO: handle error broadcast_status(ID_STATUS_OFFLINE); return; } m_hServerConn = aim_connect(bos_host, bos_port, (tls_cert_name[0] && encryption) ? true : false, bos_host); if (!m_hServerConn) { // TODO: handle error broadcast_status(ID_STATUS_OFFLINE); return; } replaceStr(COOKIE, cookie); COOKIE_LENGTH = (int)mir_strlen(cookie); ForkThread(&CAimProto::aim_protocol_negotiation, 0); }
void HTTPServerAgent::ThreadMain() { while (1) { // look for requests SDL_LockMutex(m_requestQueueLock); // if there's no requests, wait until the main thread wakes us if (m_requestQueue.empty()) SDL_CondWait(m_requestQueueCond, m_requestQueueLock); // woken up but nothing on the queue means we're being destroyed if (m_requestQueue.empty()) { // main thread is waiting for this lock, and will start // cleanup as soon as it has it SDL_UnlockMutex(m_requestQueueLock); // might be cleaned up already, so don't do anything else, // just get out of here return; } // grab a request Request req = m_requestQueue.front(); m_requestQueue.pop(); // done with the queue SDL_UnlockMutex(m_requestQueueLock); Json::FastWriter writer; req.buffer = writer.write(req.data); Response resp(req.onSuccess, req.onFail, req.userdata); curl_easy_setopt(m_curl, CURLOPT_URL, std::string(m_endpoint+"/"+req.method).c_str()); curl_easy_setopt(m_curl, CURLOPT_POSTFIELDSIZE, req.buffer.size()); curl_easy_setopt(m_curl, CURLOPT_READDATA, &req); curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, &resp); CURLcode rc = curl_easy_perform(m_curl); resp.success = rc == CURLE_OK; if (!resp.success) resp.buffer = std::string("call failed: " + std::string(curl_easy_strerror(rc))); if (resp.success) { uint32_t code; curl_easy_getinfo(m_curl, CURLINFO_RESPONSE_CODE, &code); if (code != 200) { resp.success = false; resp.buffer = stringf("call returned HTTP status: %0{d}", code); } } if (resp.success) { Json::Reader reader; resp.success = reader.parse(resp.buffer, resp.data, false); if (!resp.success) resp.buffer = std::string("JSON parse error: " + reader.getFormattedErrorMessages()); } SDL_LockMutex(m_responseQueueLock); m_responseQueue.push(resp); SDL_UnlockMutex(m_responseQueueLock); } }
bool websocket_hybi_17::handshake(url const& target) { _aspect_assert(state() == CONNECTING); // create websocket handshake request pion::http::request req(target.path_for_request()); req.add_header("Connection", "Upgrade"); req.add_header("Upgrade", "WebSocket"); req.add_header("Host", target.hostport()); req.add_header("Origin", target.origin()); string key(16, 0); std::generate(key.begin(), key.end(), rand_byte); string encoded_key; if ( !pion::algorithm::base64_encode(key, encoded_key) ) { return false; } req.add_header("Sec-WebSocket-Key", encoded_key); req.add_header("Sec-WebSocket-Version", "13"); // send request, recieve response error_code err = send_message(req); if ( !check_err(err, "send request") ) { return false; } pion::http::response resp(req); resp.receive(*tcp_conn_, err); if ( !check_err(err, "recieve response") ) { return false; } // check response if ( !is_websocket_upgrade(resp) ) { // it is not a hybi connection upgrade, give a chance for another protocol return false; } // Check reply key encoded_key += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; encoded_key = crypto::sha1_digest(encoded_key.data(), encoded_key.size()); string resp_key; if ( !pion::algorithm::base64_encode(encoded_key, resp_key) ) { return false; } if ( resp_key != resp.get_header("Sec-WebSocket-Accept") ) { return false; } state_ = OPEN; on_connect(target.to_string()); wait_data(); return true; }
void IMAPConnection::authenticateSASL() { if (!dynamicCast <security::sasl::SASLAuthenticator>(getAuthenticator())) throw exceptions::authentication_error("No SASL authenticator available."); const std::vector <string> capa = getCapabilities(); std::vector <string> saslMechs; for (unsigned int i = 0 ; i < capa.size() ; ++i) { const string& x = capa[i]; if (x.length() > 5 && (x[0] == 'A' || x[0] == 'a') && (x[1] == 'U' || x[1] == 'u') && (x[2] == 'T' || x[2] == 't') && (x[3] == 'H' || x[3] == 'h') && x[4] == '=') { saslMechs.push_back(string(x.begin() + 5, x.end())); } } if (saslMechs.empty()) throw exceptions::authentication_error("No SASL mechanism available."); std::vector <shared_ptr <security::sasl::SASLMechanism> > mechList; shared_ptr <security::sasl::SASLContext> saslContext = make_shared <security::sasl::SASLContext>(); for (unsigned int i = 0 ; i < saslMechs.size() ; ++i) { try { mechList.push_back (saslContext->createMechanism(saslMechs[i])); } catch (exceptions::no_such_mechanism&) { // Ignore mechanism } } if (mechList.empty()) throw exceptions::authentication_error("No SASL mechanism available."); // Try to suggest a mechanism among all those supported shared_ptr <security::sasl::SASLMechanism> suggestedMech = saslContext->suggestMechanism(mechList); if (!suggestedMech) throw exceptions::authentication_error("Unable to suggest SASL mechanism."); // Allow application to choose which mechanisms to use mechList = dynamicCast <security::sasl::SASLAuthenticator>(getAuthenticator())-> getAcceptableMechanisms(mechList, suggestedMech); if (mechList.empty()) throw exceptions::authentication_error("No SASL mechanism available."); // Try each mechanism in the list in turn for (unsigned int i = 0 ; i < mechList.size() ; ++i) { shared_ptr <security::sasl::SASLMechanism> mech = mechList[i]; shared_ptr <security::sasl::SASLSession> saslSession = saslContext->createSession("imap", getAuthenticator(), mech); saslSession->init(); shared_ptr <IMAPCommand> authCmd; if (saslSession->getMechanism()->hasInitialResponse()) { byte_t* initialResp = 0; size_t initialRespLen = 0; saslSession->evaluateChallenge(NULL, 0, &initialResp, &initialRespLen); string encodedInitialResp(saslContext->encodeB64(initialResp, initialRespLen)); delete [] initialResp; if (encodedInitialResp.empty()) authCmd = IMAPCommand::AUTHENTICATE(mech->getName(), "="); else authCmd = IMAPCommand::AUTHENTICATE(mech->getName(), encodedInitialResp); } else { authCmd = IMAPCommand::AUTHENTICATE(mech->getName()); } authCmd->send(dynamicCast <IMAPConnection>(shared_from_this())); for (bool cont = true ; cont ; ) { std::auto_ptr <IMAPParser::response> resp(m_parser->readResponse()); if (resp->response_done() && resp->response_done()->response_tagged() && resp->response_done()->response_tagged()->resp_cond_state()-> status() == IMAPParser::resp_cond_state::OK) { m_socket = saslSession->getSecuredSocket(m_socket); return; } else { std::vector <IMAPParser::continue_req_or_response_data*> respDataList = resp->continue_req_or_response_data(); string response; bool hasResponse = false; for (unsigned int i = 0 ; i < respDataList.size() ; ++i) { if (respDataList[i]->continue_req()) { response = respDataList[i]->continue_req()->resp_text()->text(); hasResponse = true; break; } } if (!hasResponse) { cont = false; continue; } byte_t* challenge = 0; size_t challengeLen = 0; byte_t* resp = 0; size_t respLen = 0; try { // Extract challenge saslContext->decodeB64(response, &challenge, &challengeLen); // Prepare response saslSession->evaluateChallenge (challenge, challengeLen, &resp, &respLen); // Send response const string respB64 = saslContext->encodeB64(resp, respLen) + "\r\n"; sendRaw(utility::stringUtils::bytesFromString(respB64), respB64.length()); if (m_tracer) m_tracer->traceSendBytes(respB64.length() - 2, "SASL exchange"); // Server capabilities may change when logged in invalidateCapabilities(); } catch (exceptions::sasl_exception& e) { if (challenge) { delete [] challenge; challenge = NULL; } if (resp) { delete [] resp; resp = NULL; } // Cancel SASL exchange sendRaw(utility::stringUtils::bytesFromString("*\r\n"), 3); if (m_tracer) m_tracer->traceSend("*"); } catch (...) { if (challenge) delete [] challenge; if (resp) delete [] resp; throw; } if (challenge) delete [] challenge; if (resp) delete [] resp; } } } throw exceptions::authentication_error ("Could not authenticate using SASL: all mechanisms failed."); }
HTTP_RESPONSE* resp_t::toHttpResponse(void) { // std::lock_guard< std::mutex > lck(m_mutex); HTTP_RESPONSE* resp(new HTTP_RESPONSE); HTTP_RESPONSE_HEADERS* hdrs(m_headers.getResponseHeaders()); std::string sc(getStatusString().toStdString()); //QString sc(getStatusString()); BYTE* buf(nullptr); HTTP_DATA_CHUNK* chunk(new HTTP_DATA_CHUNK); std::size_t len(m_body.size()); ::memset(resp, 0, sizeof(HTTP_RESPONSE)); resp->StatusCode = m_status; resp->pReason = new CHAR[sc.length() + 1]; ::memset((void*)resp->pReason, 0, sc.length() + 1); ::memcpy_s((void*)resp->pReason, sc.length() + 1, sc.c_str(), sc.length()); resp->ReasonLength = ::strlen(resp->pReason); if (INT_MAX <= len) throw std::runtime_error("http::resp_t::toHttpResponse(): Overly large HTTP response encountered"); buf = new BYTE[len + 1]; ::memset(buf, 0, len + 1); ::memcpy_s(buf, len + 1, m_body.constData(), len); chunk->DataChunkType = HTTP_DATA_CHUNK_TYPE::HttpDataChunkFromMemory; chunk->FromMemory.pBuffer = buf; chunk->FromMemory.BufferLength = len; resp->pEntityChunks = chunk; resp->EntityChunkCount = 1; if (nullptr != hdrs) { ::memcpy_s(resp->Headers.KnownHeaders, sizeof(resp->Headers.KnownHeaders), hdrs->KnownHeaders, sizeof(hdrs->KnownHeaders)); resp->Headers.pTrailers = hdrs->pTrailers; resp->Headers.TrailerCount = hdrs->TrailerCount; resp->Headers.UnknownHeaderCount = hdrs->UnknownHeaderCount; if (0 != hdrs->UnknownHeaderCount) { //USHORT l = hdrs->UnknownHeaderCount; //if (USHRT_MAX-1 < l) // throw std::runtime_error("http::resp_t::toHttpResponse(): Unusually large volume of unknown HTTP headers, aborting response."); //resp->Headers.pUnknownHeaders = new HTTP_UNKNOWN_HEADER[l+1]; /*for (auto idx = 0; idx < l; idx++) { resp->Headers.pUnknownHeaders[idx].NameLength = hdrs->pUnknownHeaders[idx].NameLength; resp->Headers.pUnknownHeaders[idx].RawValueLength = hdrs->pUnknownHeaders[idx].RawValueLength; resp->Headers.pUnknownHeaders[idx].pName = hdrs->pUnknownHeaders[idx].pName; */ resp->Headers.pUnknownHeaders = hdrs->pUnknownHeaders; //::memcpy_s(resp->Headers.pUnknownHeaders, (l+1)*sizeof(HTTP_UNKNOWN_HEADER), hdrs->pUnknownHeaders, l*sizeof(HTTP_UNKNOWN_HEADER)); } //m_headers.destroyResponseHeaders(hdrs); } //m_log.info("unknown headers count: " + QString::number(resp->Headers.UnknownHeaderCount) + " name: " + QString(resp->Headers.pUnknownHeaders[0].pName) + " value: " + QString(resp->Headers.pUnknownHeaders[0].pRawValue)); return resp; }
int LibEventServerWithTakeover::getAcceptSocket() { int ret; const char *address = m_address.empty() ? nullptr : m_address.c_str(); if (m_accept_sock != -1) { Logger::Warning("LibEventServerWithTakeover trying to get a socket, " "but m_accept_sock is not -1. Possibly leaking file descriptors."); m_accept_sock = -1; } ret = evhttp_bind_socket_backlog_fd(m_server, address, m_port, RuntimeOption::ServerBacklog); if (ret >= 0) { Logger::Info("takeover: bound directly to port %d", m_port); m_accept_sock = ret; return 0; } else if (errno != EADDRINUSE) { return -1; } if (m_transfer_fname.empty()) { return -1; } Logger::Info("takeover: beginning listen socket acquisition"); uint8_t fd_request[3] = P_VERSION C_FD_REQ; uint8_t fd_response[3] = {0,0,0}; uint32_t response_len = sizeof(fd_response); afdt_error_t err = AFDT_ERROR_T_INIT; // TODO(dreiss): Make this timeout configurable. struct timeval timeout = { 2 , 0 }; ret = afdt_sync_client( m_transfer_fname.c_str(), fd_request, sizeof(fd_request) - 1, fd_response, &response_len, &m_accept_sock, &timeout, &err); if (ret < 0) { fd_transfer_error_hander(&err, nullptr); errno = EADDRINUSE; return -1; } else if (m_accept_sock < 0) { String resp((const char*)fd_response, response_len, CopyString); Logger::Error( "AFDT did not receive a file descriptor: " "response = '%s'", StringUtil::CEncode(resp, null_string).data()); errno = EADDRINUSE; return -1; } Logger::Info("takeover: acquired listen socket"); m_took_over = true; ret = evhttp_accept_socket(m_server, m_accept_sock); if (ret < 0) { Logger::Error("evhttp_accept_socket: %s", folly::errnoStr(errno).c_str()); int errno_save = errno; close(m_accept_sock); m_accept_sock = -1; errno = errno_save; return -1; } return 0; }
bool HttpPost(const WCHAR *server, const WCHAR *url, str::Str<char> *headers, str::Str<char> *data) { str::Str<char> resp(2048); bool ok = false; DWORD flags = 0; char *hdr = nullptr; DWORD hdrLen = 0; HINTERNET hConn = nullptr, hReq = nullptr; void *d = nullptr; DWORD dLen = 0; unsigned int timeoutMs = 15 * 1000; // Get the response status. DWORD respHttpCode = 0; DWORD respHttpCodeSize = sizeof(respHttpCode); DWORD dwRead = 0; HINTERNET hInet = InternetOpen(USER_AGENT, INTERNET_OPEN_TYPE_PRECONFIG, nullptr, nullptr, 0); if (!hInet) goto Exit; hConn = InternetConnect(hInet, server, INTERNET_DEFAULT_HTTP_PORT, nullptr, nullptr, INTERNET_SERVICE_HTTP, 0, 1); if (!hConn) goto Exit; hReq = HttpOpenRequest(hConn, L"POST", url, nullptr, nullptr, nullptr, flags, 0); if (!hReq) goto Exit; if (headers && headers->Count() > 0) { hdr = headers->Get(); hdrLen = (DWORD)headers->Count(); } if (data && data->Count() > 0) { d = data->Get(); dLen = (DWORD)data->Count(); } InternetSetOption(hReq, INTERNET_OPTION_SEND_TIMEOUT, &timeoutMs, sizeof(timeoutMs)); InternetSetOption(hReq, INTERNET_OPTION_RECEIVE_TIMEOUT, &timeoutMs, sizeof(timeoutMs)); if (!HttpSendRequestA(hReq, hdr, hdrLen, d, dLen)) goto Exit; HttpQueryInfo(hReq, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &respHttpCode, &respHttpCodeSize, 0); do { char buf[1024]; if (!InternetReadFile(hReq, buf, sizeof(buf), &dwRead)) goto Exit; ok = resp.AppendChecked(buf, dwRead); if (!ok) goto Exit; } while (dwRead > 0); #if 0 // it looks like I should be calling HttpEndRequest(), but it always claims // a timeout even though the data has been sent, received and we get HTTP 200 if (!HttpEndRequest(hReq, nullptr, 0, 0)) { LogLastError(); goto Exit; } #endif ok = (200 == respHttpCode); Exit: if (hReq) InternetCloseHandle(hReq); if (hConn) InternetCloseHandle(hConn); if (hInet) InternetCloseHandle(hInet); return ok; }
int DeviceServiceImpl::GetScopes(_tds__GetScopes *tds__GetScopes, _tds__GetScopesResponse *tds__GetScopesResponse) { DevGetScopesResponse resp(tds__GetScopesResponse); resp.AddItems( m_pBaseServer->m_scopes ); return SOAP_OK; }
void do_respond(const Iriss::Command& cmd, int16_t *channels) { uint32_t directives = cmd.get(); if(directives == Iriss::Command::TX_ERR) { return; } if(directives & Iriss::Command::ACK) { // reply with an ACK if not waiting on one if(!piOnline) { Iriss::Command resp(Iriss::Command::ACK); hal.console->write(&Iriss::BEGIN_UART_MESSAGE, 1); uint8_t lenBuf[4]; Utils::Packable::pack_uint32(Iriss::Command::PACKED_SIZE, lenBuf); hal.console->write(lenBuf, sizeof(Iriss::Command::PACKED_SIZE)); uint8_t cmdBuf[Iriss::Command::PACKED_SIZE]; resp.pack(cmdBuf, Iriss::Command::PACKED_SIZE); hal.console->write(cmdBuf, Iriss::Command::PACKED_SIZE); piOnline = true; } } if(directives & Iriss::Command::SEND_AGAIN) { // send the last command Iriss::Command resp; resp.set(lastSent); hal.console->write(&Iriss::BEGIN_UART_MESSAGE, 1); uint8_t lenBuf[4]; Utils::Packable::pack_uint32(Iriss::Command::PACKED_SIZE, lenBuf); hal.console->write(lenBuf, sizeof(Iriss::Command::PACKED_SIZE)); uint8_t cmdBuf[Iriss::Command::PACKED_SIZE]; resp.pack(cmdBuf, Iriss::Command::PACKED_SIZE); hal.console->write(cmdBuf, Iriss::Command::PACKED_SIZE); } if(directives & Iriss::Command::GET_ORIENTATION) { // get the orientation from ins and send it ins.update(); float roll,pitch,yaw; ins.quaternion.to_euler(&roll, &pitch, &yaw); roll = ToDeg(roll); pitch = ToDeg(pitch); yaw = ToDeg(yaw); Iriss::Orientation orientation(roll, pitch, yaw); hal.console->write(&Iriss::BEGIN_UART_MESSAGE, 1); uint8_t lenBuf[4]; Utils::Packable::pack_uint32(Iriss::Orientation::PACKED_SIZE, lenBuf); hal.console->write(lenBuf, sizeof(Iriss::Command::PACKED_SIZE)); uint8_t orientBuf[Iriss::Orientation::PACKED_SIZE]; orientation.pack(orientBuf, Iriss::Orientation::PACKED_SIZE); hal.console->write(orientBuf, Iriss::Orientation::PACKED_SIZE); } if(directives & Iriss::Command::NUDGE_ROLL_LEFT) { // update channels 0 --channels[0]; } if(directives & Iriss::Command::NUDGE_ROLL_RIGHT) { // update channels 0 in the other way from LEFT ++channels[0]; } if(directives & Iriss::Command::NUDGE_UP) { // update channels 2 ++channels[2]; } if(directives & Iriss::Command::NUDGE_DOWN) { // update channels 2 in the other way from UP --channels[2]; } if(directives & Iriss::Command::NUDGE_YAW_CCW) { // update channels 3 ++channels[3]; } if(directives & Iriss::Command::NUDGE_YAW_CW) { // update channels 3 in the other way from CCW --channels[3]; } if(directives & Iriss::Command::NUDGE_PITCH_DOWN) { // update channels 1 ++channels[1]; } if(directives & Iriss::Command::NUDGE_PITCH_UP) { // update channels 1 in the other way from DOWN --channels[1]; } }
void Protocol::HandleBusReq(SingleCache& cache, Bus& bus) { if (bus.pending_acks[cache.pid]) { assert(!cache.incoming_bus_req_queue.empty()); BusReq bus_req = cache.incoming_bus_req_queue.front(); // cache does not need to handle write back if (bus_req.cmd == BUS_CMD_WB) { BusAck ack(false, false); bus.SendToAckWire(ack, cache.pid); cache.incoming_bus_req_queue.pop(); return; } // handle conflict with the pending outgoing bus request if (!cache.outgoing_bus_req_queue.empty()) { BusReq& local_req = cache.outgoing_bus_req_queue.front(); if (local_req.addr == bus_req.addr) { if (local_req.cmd == BUS_CMD_WB && (bus_req.cmd == BUS_CMD_RDX_M || bus_req.cmd == BUS_CMD_RD_M)) { cache.outgoing_bus_req_queue.pop(); } if (local_req.cmd == BUS_CMD_RDX_H || bus_req.cmd == BUS_CMD_RDX_M) { local_req.cmd = BUS_CMD_RDX_M; } } } // not present in cache if (!cache.IsHit(bus_req.addr)) { BusAck ack(false, false); bus.SendToAckWire(ack, cache.pid); cache.incoming_bus_req_queue.pop(); return; } // the requested cacheline is in the current cache CacheLine& line = cache.GetHitLine(bus_req.addr); assert(!bus.curr_ack.dirty); // the requestor does not have the data, someone needs to respond if (bus_req.cmd == BUS_CMD_RD_M || bus_req.cmd == BUS_CMD_RDX_M) { if (line.state == CACHE_LINE_STATE_M) { // this is the only owner of the line, need to respond assert(!bus.curr_ack.shared); if (cache.outgoing_bus_resp_queue.full()) { return; } BusResp resp(bus_req.tag); cache.outgoing_bus_resp_queue.push(resp); cache_to_cache++; // do not update local line, this will be done when data sent // send ack BusAck ack(false, true); bus.SendToAckWire(ack, cache.pid); cache.incoming_bus_req_queue.pop(); return; } else if (line.state == CACHE_LINE_STATE_S) { // first sharer respond if (!bus.curr_ack.shared) { if (cache.outgoing_bus_resp_queue.full()) { return; } BusResp resp(bus_req.tag); cache.outgoing_bus_resp_queue.push(resp); cache_to_cache++; // do not update local line, this will be done when data sent // send ack BusAck ack(true, false); bus.SendToAckWire(ack, cache.pid); cache.incoming_bus_req_queue.pop(); return; } } else { assert(false); } } // no need to respond // update local line state if needed assert(line.state != CACHE_LINE_STATE_M); if (bus_req.cmd == BUS_CMD_RDX_H || bus_req.cmd == BUS_CMD_RDX_M) { line.valid = false; } else if (bus_req.cmd == BUS_CMD_RD_M) { line.state = CACHE_LINE_STATE_S; } else { assert(false); } // send ack if (line.state == CACHE_LINE_STATE_S) { BusAck ack(true, false); bus.SendToAckWire(ack, cache.pid); } else { assert(false); } // complete the current request cache.incoming_bus_req_queue.pop(); return; } }
string WhatsAppProto::Register(int state, string cc, string number, string code) { string idx; string ret; DBVARIANT dbv; if ( WASocketConnection::hNetlibUser == NULL) { NotifyEvent(m_tszUserName, TranslateT("Network-connection error."), NULL, WHATSAPP_EVENT_CLIENT); return ret; } if ( !getString(WHATSAPP_KEY_IDX, &dbv)) { idx = dbv.pszVal; db_free(&dbv); } if (idx.empty()) { std::stringstream tm; tm << time(NULL); BYTE idxBuf[16]; utils::md5string(tm.str(), idxBuf); idx = std::string((const char*) idxBuf, 16); setString(WHATSAPP_KEY_IDX, idx.c_str()); } string url; if (state == REG_STATE_REQ_CODE) { unsigned char digest[16]; utils::md5string(std::string(ACCOUNT_TOKEN_PREFIX1) + ACCOUNT_TOKEN_PREFIX2 + number, digest); url = string(ACCOUNT_URL_CODEREQUESTV2); url += "?lc=US&lg=en&mcc=000&mnc=000&method=sms&token=" + Utilities::bytesToHex(digest, 16); } else if (state == REG_STATE_REG_CODE) { url = string(ACCOUNT_URL_REGISTERREQUESTV2); url += "?code="+ code; } url += "&cc="+ cc +"&in="+ number +"&id="+ idx; NETLIBHTTPREQUEST nlhr = {sizeof(NETLIBHTTPREQUEST)}; nlhr.requestType = REQUEST_POST; nlhr.szUrl = (char*) url.c_str(); nlhr.headers = s_registerHeaders; nlhr.headersCount = SIZEOF(s_registerHeaders); nlhr.flags = NLHRF_HTTP11 | NLHRF_GENERATEHOST | NLHRF_REMOVEHOST | NLHRF_SSL; NETLIBHTTPREQUEST* pnlhr = (NETLIBHTTPREQUEST*) CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM) WASocketConnection::hNetlibUser, (LPARAM)&nlhr); string title = this->TranslateStr("Registration"); if (pnlhr == NULL) { this->NotifyEvent(title, this->TranslateStr("Registration failed. Invalid server response."), NULL, WHATSAPP_EVENT_CLIENT); return ret; } debugLogA("Server response: %s", pnlhr->pData); MessageBoxA(NULL, pnlhr->pData, "Debug", MB_OK); JSONROOT resp(pnlhr->pData); if (resp == NULL) { this->NotifyEvent(title, this->TranslateStr("Registration failed. Invalid server response."), NULL, WHATSAPP_EVENT_CLIENT); return ret; } // Status = fail JSONNODE *val = json_get(resp, "status"); if (!lstrcmp( ptrT(json_as_string(val)), _T("fail"))) { JSONNODE *tmpVal = json_get(resp, "reason"); if (!lstrcmp( ptrT(json_as_string(tmpVal)), _T("stale"))) this->NotifyEvent(title, this->TranslateStr("Registration failed due to stale code. Please request a new code"), NULL, WHATSAPP_EVENT_CLIENT); else this->NotifyEvent(title, this->TranslateStr("Registration failed."), NULL, WHATSAPP_EVENT_CLIENT); tmpVal = json_get(resp, "retry_after"); if (tmpVal != NULL) this->NotifyEvent(title, this->TranslateStr("Please try again in %i seconds", json_as_int(tmpVal)), NULL, WHATSAPP_EVENT_OTHER); } // Request code else if (state == REG_STATE_REQ_CODE) { if ( !lstrcmp( ptrT(json_as_string(val)), _T("sent"))) this->NotifyEvent(title, this->TranslateStr("Registration code has been sent to your phone."), NULL, WHATSAPP_EVENT_OTHER); } // Register else if (state == REG_STATE_REG_CODE) { val = json_get(resp, "pw"); if (val == NULL) this->NotifyEvent(title, this->TranslateStr("Registration failed."), NULL, WHATSAPP_EVENT_CLIENT); else ret = _T2A( ptrT(json_as_string(val))); } json_delete(resp); return ret; }
void instance::on_cast_spell(const Event& inEvt) { if (!inEvt.hasProperty("Spell")) { Event evt(inEvt); reject(evt); return; } // find the spell object Spell* lSpell; try { lSpell = get_spell(convertTo<int>(inEvt.getProperty("Spell"))); } catch (invalid_uid& e) { // reject the event log_->errorStream() << "couldn't find requested Spell with id " << inEvt.getProperty("Spell"); Event evt(inEvt); reject(evt); return; } Entity* lCaster = lSpell->getCaster(); assert(lCaster && lSpell); log_->debugStream() << "spell cast: " << lSpell->getUID() << "#" << lSpell->getName(); log_->debugStream() << "caster: " << lCaster->getUID() << "#" << lCaster->getName(); // allow only ALL or CASTING spells to be cast by active puppets if (lSpell->getPhase() != BLOCKING && active_puppet_->getUID() != lCaster->getOwner()->getUID()) { Event evt(inEvt); return reject(evt); } // blocking spells can only be cast when the active is not the caster else if (lSpell->getPhase() == BLOCKING && active_puppet_->getUID() == lCaster->getOwner()->getUID()) { Event evt(inEvt); return reject(evt); } Entity* lTarget = 0; if (inEvt.hasProperty("T")) { try { // is the target a puppet? lTarget = get_puppet(convertTo<int>(inEvt.getProperty("T"))).get(); log_->debugStream() << "target: " << lTarget->getUID() << "#" << lTarget->getName(); } catch (invalid_uid& e) { try { // a unit? lTarget = get_unit(convertTo<int>(inEvt.getProperty("T"))); log_->debugStream() << "target: " << lTarget->getUID() << "#" << lTarget->getName(); } catch (invalid_uid& e) { // invalid UID log_->errorStream() << "couldn't find spell target with id " << inEvt.getProperty("T"); Event evt(inEvt); reject(evt); return; } } assert(lTarget); lSpell->setTarget(lTarget); } else { // if the spell requires a target, it must be given #ifdef PARANOID assert(!lSpell->requiresTarget()); #else // gracefully reject the event if (lSpell->requiresTarget()) { log_->errorStream() << "an invalid spell request#" << lSpell->getUID() << "; target is required but not given"; Event e(inEvt); return reject(e); } #endif // otherwise, the spell's target is the caster itself lSpell->setTarget(lCaster); } // verify the caster having enough resources to cast the spell { bool valid = true; if (lCaster->getRank() == PUPPET) { if (lSpell->getCostWP() > ((Puppet*)lCaster)->getWP()) valid = valid && false; // heroes can't have less than 1 channel if (lSpell->getCostChannels() >= ((Puppet*)lCaster)->getChannels()) valid = valid && false; } if (lSpell->getCostHP() > lCaster->getHP()) valid = valid && false; if (!valid) { if (lCaster->getRank() == PUPPET) { Puppet* tCaster = (Puppet*)lCaster; log_->errorStream() << "caster" << tCaster->getUID() << " failed the resources requirements of the spell" << lSpell->getUID() << " : \t " << lSpell->getCostWP() << ":" << lSpell->getCostHP() << ":" << lSpell->getCostChannels() << " vs " << tCaster->getWP() << ":" << tCaster->getHP() << ":" << tCaster->getChannels(); } Event e(inEvt); return reject(e); } } // prepare the response event Event resp(inEvt); resp.setProperty("Spell", lSpell->getUID()); resp.setProperty("C", lSpell->getCaster()->getUID()); if (lSpell->requiresTarget()) resp.setProperty("T", lSpell->getTarget()->getUID()); // dispatch to Lua /*lua_getfield(lua_, LUA_GLOBALSINDEX, "process_spell"); if(!lua_isfunction(lua_, 1)) { log_->errorStream() << "could not find Lua event processor!"; lua_pop(lua_,1); Event e(inEvt); return reject(e); } log_->debugStream() << "\t things are looking good, passing to lua: " << ", cost: " << lSpell->getCostWP() << ":" << lSpell->getCostHP() << ":" << lSpell->getCostChannels(); tolua_pushusertype(lua_,(void*)lCaster,"Pixy::Entity"); tolua_pushusertype(lua_,(void*)lTarget,"Pixy::Entity"); tolua_pushusertype(lua_,(void*)lSpell,"Pixy::Spell"); tolua_pushusertype(lua_,(void*)&inEvt,"Pixy::Event"); try { lua_call(lua_, 4, 1); } catch (std::exception& e) { log_->errorStream() << "Lua Handler: " << e.what(); } bool result = lua_toboolean(lua_, lua_gettop(lua_)); lua_remove(lua_, lua_gettop(lua_));*/ bool result = pass_to_lua( "Spells.onCastSpell", 3, "Pixy::Entity", lCaster, "Pixy::Entity", lTarget, "Pixy::Spell", lSpell); log_->debugStream() << "\t back from lua: " << ", cost: " << lSpell->getCostWP() << ":" << lSpell->getCostHP() << ":" << lSpell->getCostChannels(); // if the spell cast was successful, we first broadcast the command to // the clients, then detach the spell from the caster, and finally // we apply any resource changes to the caster and broadcast them too if (result) { // broadcast the CastSpell event to players, confirming it { resp.Feedback = EventFeedback::Ok; broadcast(resp); } // update the caster stats and broadcast them { Event evt(EventUID::Unassigned, EventFeedback::Ok); evt.setProperty("UID", lCaster->getUID()); if (lCaster->getRank() == PUPPET) { Puppet* tCaster = static_cast<Puppet*>(lCaster); evt.UID = EventUID::UpdatePuppet; // apply WP cost, if any if (lSpell->getCostWP() > 0) { tCaster->setWP(tCaster->getWP() - lSpell->getCostWP()); evt.setProperty("WP", tCaster->getWP()); log_->debugStream() << tCaster->getName() << " paid " << lSpell->getCostWP() << " wp," << " and now has " << tCaster->getWP() << " wp."; } // apply the Channels cost, if any if (lSpell->getCostChannels() > 0) { tCaster->setChannels(tCaster->getChannels() - lSpell->getCostChannels()); evt.setProperty("Channels", tCaster->getChannels()); log_->debugStream() << tCaster->getName() << " paid " << lSpell->getCostChannels() << " channels," << " and now has " << tCaster->getChannels() << " channels."; } } else evt.UID = EventUID::UpdateUnit; // apply HP cost, if any if (lSpell->getCostHP() > 0) { lCaster->setHP(lCaster->getHP() - lSpell->getCostHP()); evt.setProperty("HP", lCaster->getHP()); log_->debugStream() << lCaster->getName() << " paid " << lSpell->getCostHP() << " hp," << " and now has " << lCaster->getHP() << " hp."; } broadcast(evt); } // don't delete the spell object if it's a buff lCaster->detachSpell(lSpell->getUID(), lSpell->getDuration() == 0); } else { // we reject the request //Event e(inEvt); resp.Feedback = EventFeedback::Error; return reject(resp); } lSpell = 0; lCaster = 0; lTarget = 0; //return result; }
void handle_client_request(Client_handle client_handle, const Request_msg& client_req) { std::string request_string = client_req.get_request_string(); std::string request_arg = client_req.get_arg("cmd"); DLOG(INFO) << ">>Received request: " << request_string << std::endl; // You can assume that traces end with this special message. It // exists because it might be useful for debugging to dump // information about the entire run here: statistics, etc. if (request_arg == "lastrequest") { Response_msg resp(0); resp.set_response("ack"); send_client_response(client_handle, resp); return; } // cache early response if (cache_manager.cacheMap.find(request_string) != cache_manager.cacheMap.end()) { std::string response_string = cache_manager.cacheMap[request_string]; Response_msg resp; resp.set_response(response_string); send_client_response(client_handle, resp); // hit and return return; } bool is_assigned = false; mstate.num_pending_client_requests++; // Assign to worker base on its work_status // assign to low workload node if (request_arg == "418wisdom") { // Level 1 for(unsigned int i = 0; i < mstate.my_workers.size(); i++) { RESERVE_CONTEXT_FOR_PI_LEVEL1(1); if(mstate.my_workers[i].num_running_task <= MAX_EXEC_CONTEXT_LEVEL1) { send_and_update(client_handle, mstate.my_workers[i].worker_handle, client_req, i, WISDOM); is_assigned = true; break; } } // Level 2 if (!is_assigned) { for(unsigned int i = 0; i < mstate.my_workers.size(); i++) { RESERVE_CONTEXT_FOR_PI_LEVEL2(1); if(mstate.my_workers[i].num_running_task <= MAX_EXEC_CONTEXT_LEVEL2) { send_and_update(client_handle, mstate.my_workers[i].worker_handle, client_req, i, WISDOM); is_assigned = true; break; } } } } // assign to idle node if (request_arg == "projectidea") { if (!is_assigned) { for(unsigned int i=0; i<mstate.my_workers.size(); i++) { if(mstate.my_workers[i].num_running_task <= MAX_EXEC_CONTEXT_LEVEL2 + 1 && mstate.my_workers[i].num_work_type[PROJECTIDEA] == 0) { send_and_update(client_handle, mstate.my_workers[i].worker_handle, client_req, i, PROJECTIDEA); is_assigned = true; break; } } } } // find any possible spot if (request_arg == "tellmenow") { // Level 1 for(unsigned int i=0; i<mstate.my_workers.size(); i++) { if(mstate.my_workers[i].num_running_task < MAX_EXEC_CONTEXT_LEVEL1) { send_and_update(client_handle, mstate.my_workers[i].worker_handle, client_req, i, TELLMENOW); is_assigned = true; break; } } // // Level 2 if (!is_assigned) { for(unsigned int i=0; i<mstate.my_workers.size(); i++) { if(mstate.my_workers[i].num_running_task < MAX_EXEC_CONTEXT_LEVEL2) { send_and_update(client_handle, mstate.my_workers[i].worker_handle, client_req, i, TELLMENOW); is_assigned = true; break; } } } } // find node that has low workload if (request_arg == "countprimes") { // Level 1 for(unsigned int i=0; i<mstate.my_workers.size(); i++) { RESERVE_CONTEXT_FOR_PI_LEVEL1(1); if(mstate.my_workers[i].num_running_task < MAX_EXEC_CONTEXT_LEVEL1) { send_and_update(client_handle, mstate.my_workers[i].worker_handle, client_req, i, COUNTPRIMES); is_assigned = true; break; } } // Level 2 if (!is_assigned) { for(unsigned int i=0; i<mstate.my_workers.size(); i++) { RESERVE_CONTEXT_FOR_PI_LEVEL2(1); if(mstate.my_workers[i].num_running_task < MAX_EXEC_CONTEXT_LEVEL2) { send_and_update(client_handle, mstate.my_workers[i].worker_handle, client_req, i, COUNTPRIMES); is_assigned = true; break; } } } } // find node that has more than 4 context if (request_arg == "compareprimes") { // Level 1 for(unsigned int i=0; i<mstate.my_workers.size(); i++) { RESERVE_CONTEXT_FOR_PI_LEVEL1(4); ///only execute if remianing context > 4 if(MAX_EXEC_CONTEXT_LEVEL1 - mstate.my_workers[i].num_running_task < 4) continue; send_and_update(client_handle, mstate.my_workers[i].worker_handle, client_req, i, COMPAREPRIMES); is_assigned = true; break; } // Level 2 if (!is_assigned) { for(unsigned int i=0; i<mstate.my_workers.size(); i++) { RESERVE_CONTEXT_FOR_PI_LEVEL2(4); ///only execute if remianing context > 4 if(MAX_EXEC_CONTEXT_LEVEL2 - mstate.my_workers[i].num_running_task < 4) continue; send_and_update(client_handle, mstate.my_workers[i].worker_handle, client_req, i, COMPAREPRIMES); is_assigned = true; break; } } } //if all workers are busy, push the request to queue if(!is_assigned) { if (request_arg == "tellmenow" || request_arg == "projectidea") { DLOG(INFO) << "enque vip:" << client_req.get_tag() << ":" << client_req.get_request_string() << std::endl; mstate.requests_queue_vip.push(Request_info(client_handle, client_req)); } else { DLOG(INFO) << "enque:" << client_req.get_tag() << ":" << client_req.get_request_string() << std::endl; mstate.requests_queue.push(Request_info(client_handle, client_req)); } } // We're done! This event handler now returns, and the master // process calls another one of your handlers when action is // required. return; }
MValue InsertMaker::MakeInsert() { last_error.clear(); std::string table_name = statement->GetName(); int space_id = tinfo->SpaceBy(table_name)->ID(); if (space_id == -1) { last_error = "InsertMaker::MakeInsert(): space with name '" + table_name + "' was not found in schema"; LogFL(DEBUG) << last_error << "\n"; return MValue(false); } size_t msg_size = MSG_START_SIZE; TP_p request(new TP(DataStructure(msg_size))); auto space_format = tinfo->SpaceFormat(space_id); auto values = statement->GetValues(); if (values == NULL) { last_error = "InsertMaker::MakeInsert(): attempt to insert empty tuple"; LogFL(DEBUG) << last_error << "\n"; return MValue(false); } size_t values_size = values->size(); request->AddInsert(space_id); request->ReserveTupleFields(space_format.size()); if (statement->GetColumns() == NULL) { size_t size = space_format.size(); for (size_t i = 0; (i < size) && (i < values_size); ++i) { switch(values->at(i)->GetType()) { case kExprLiteralFloat: { request->AddFloat(values->at(i)->GetFloat()); break; } case kExprLiteralString: { request->AddString(values->at(i)->GetString()); break; } case kExprLiteralInt: { request->AddInt(values->at(i)->GetInt()); break; } default: { last_error = "InsertMaker::MakeInsert(): expr with type = " + ExprTypeToString(values->at(i)->GetType()) + " can't be added to insert"; LogFL(DEBUG) << last_error << "\n"; return MValue(false); } } } for (size_t i = values_size; i < size; ++i) { switch(space_format[i].type) { case FT_STR: request->AddString(""); break; case FT_NUM: request->AddInt(0); break; default: { last_error = "InsertMaker::MakeInsert(): type of value = " + Convert::ToString(space_format[i].type) + " can't be added to request\n"; LogFL(DEBUG) << last_error << "\n"; return MValue(false); } } } } else { if (statement->GetColumns()->size() != statement->GetValues()->size()) { last_error = "InsertMaker::MakeInsert(): count of columns and values are not equal"; LogFL(DEBUG) << last_error << "\n"; return MValue(false); } for (size_t i = 0, size = space_format.size(); i < size; ++i) { std::string &col_name = space_format[i].name; auto val = statement->GetValueByColumn(col_name); if (val != NULL) { switch(val->GetType()) { case kExprLiteralFloat: { request->AddFloat(val->GetFloat()); break; } case kExprLiteralString: { request->AddString(val->GetString()); break; } case kExprLiteralInt: { request->AddInt(val->GetInt()); break; } default: { last_error = "InsertMaker::MakeInsert(): type of value = " + ExprTypeToString(val->GetType()) + " can't be added to request"; LogFL(DEBUG) << last_error << "\n"; return MValue(false); } } continue; } switch(space_format[i].type) { case FT_NUM: request->AddInt(0); break; case FT_STR: request->AddString(""); break; default: { last_error = "InsertMaker::MakeInsert(): type of value = " + Convert::ToString(space_format[i].type) + " can't be added to request"; LogFL(DEBUG) << last_error << "\n"; return MValue(false); } } } } TPResponse resp(ses->SendRequest(request)); if (resp.GetState() == -1) { last_error = "InsertMaker::MakeInsert(): failed to parse response"; LogFL(DEBUG) << last_error << "\n"; return MValue(false); } if (resp.GetCode() != 0) { std::stringstream tmp; tmp << "InsertMaker::MakeInsert(): server respond: " << resp.GetCode() << ", " << resp.GetError(); last_error = tmp.str(); LogFL(DEBUG) << last_error << "\n"; return MValue(false); } return MValue::FromMSGPack(resp.GetData()); }
// virtual LLIOPipe::EStatus LLSDRPCClient::process_impl( const LLChannelDescriptors& channels, buffer_ptr_t& buffer, bool& eos, LLSD& context, LLPumpIO* pump) { PUMP_DEBUG; LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT); if((STATE_NONE == mState) || (!pump)) { // You should have called the call() method already. return STATUS_PRECONDITION_NOT_MET; } EStatus rv = STATUS_DONE; switch(mState) { case STATE_READY: { PUMP_DEBUG; // lldebugs << "LLSDRPCClient::process_impl STATE_READY" << llendl; buffer->append( channels.out(), (U8*)mRequest.c_str(), mRequest.length()); context[CONTEXT_DEST_URI_SD_LABEL] = mURI; mState = STATE_WAITING_FOR_RESPONSE; break; } case STATE_WAITING_FOR_RESPONSE: { PUMP_DEBUG; // The input channel has the sd response in it. //lldebugs << "LLSDRPCClient::process_impl STATE_WAITING_FOR_RESPONSE" // << llendl; LLBufferStream resp(channels, buffer.get()); LLSD sd; LLSDSerialize::fromNotation(sd, resp, buffer->count(channels.in())); LLSDRPCResponse* response = (LLSDRPCResponse*)mResponse.get(); if (!response) { mState = STATE_DONE; break; } response->extractResponse(sd); if(EPBQ_PROCESS == mQueue) { LLPumpIO::chain_t chain; chain.push_back(mResponse); pump->addChain(chain, DEFAULT_CHAIN_EXPIRY_SECS); } else { pump->respond(mResponse.get()); } mState = STATE_DONE; break; } case STATE_DONE: default: PUMP_DEBUG; llinfos << "invalid state to process" << llendl; rv = STATUS_ERROR; break; } return rv; }
void TerminalApiClient::data_tick() { // values in milliseconds const int MIN_WAIT_TIME = 20; // sleep time must be smaller or equal than the smallest period const int IO_POLL_PERIOD = 20; const int API_EVENT_POLL_PERIOD = 1000; int last_io_poll = 0; int last_event_api_poll = 0; int last_char = 0; std::string inbuf; bool enter_was_pressed = false; StateToken runstate_state_token; std::string runstate; std::vector<std::string> accounts; StateToken password_state_token; bool ask_for_password = false; std::string key_name; TerminalInput term; while(!shouldStop()) { // assuming sleep_time >> work_time // so we don't have to check the absolute time, just sleep every cycle usleep(MIN_WAIT_TIME * 1000); last_io_poll += MIN_WAIT_TIME; last_event_api_poll += MIN_WAIT_TIME; if(last_io_poll >= IO_POLL_PERIOD) { last_io_poll = 0; last_char = 0; if(term.kbhit()) { enter_was_pressed = false; last_char = term.getch(); if(last_char > 127) std::cout << "Warning: non ASCII characters probably won't work." << std::endl; if(last_char >= ' ')// space is the first printable ascii character inbuf += (char) last_char; if(last_char == '\r' || last_char == '\n') enter_was_pressed = true; else enter_was_pressed = false; // send echo if(ask_for_password) std::cout << "*"; else std::cout << (char) last_char; //std::cout << "you pressed key " << (char) last_char << " as integer: " << last_char << std::endl; } } if(last_event_api_poll >= API_EVENT_POLL_PERIOD) { last_event_api_poll = 0; if(!runstate_state_token.isNull() && !isTokenValid(runstate_state_token)) runstate_state_token = StateToken(); // must get new state with new token if(!password_state_token.isNull() && !isTokenValid(password_state_token)) password_state_token = StateToken(); } bool edge = false; if(runstate_state_token.isNull()) { edge = true; JsonStream reqs; JsonStream resps; Request req(reqs); std::stringstream ss; Response resp(resps, ss); req.mPath.push("runstate"); req.mPath.push("control"); reqs.switchToDeserialisation(); ApiServer::RequestId id = mApiServer->handleRequest(req, resp); waitForResponse(id); resps.switchToDeserialisation(); resps << makeKeyValueReference("runstate", runstate); runstate_state_token = resp.mStateToken; } if(password_state_token.isNull()) { edge = true; JsonStream reqs; JsonStream resps; Request req(reqs); std::stringstream ss; Response resp(resps, ss); req.mPath.push("password"); req.mPath.push("control"); reqs.switchToDeserialisation(); ApiServer::RequestId id = mApiServer->handleRequest(req, resp); waitForResponse(id); resps.switchToDeserialisation(); resps << makeKeyValueReference("want_password", ask_for_password); resps << makeKeyValueReference("key_name", key_name); password_state_token = resp.mStateToken; } if(!ask_for_password && edge && runstate == "waiting_account_select") { JsonStream reqs; JsonStream resps; Request req(reqs); std::stringstream ss; Response resp(resps, ss); req.mPath.push("locations"); req.mPath.push("control"); reqs.switchToDeserialisation(); ApiServer::RequestId id = mApiServer->handleRequest(req, resp); waitForResponse(id); resps.switchToDeserialisation(); std::cout << "Type a number to select an account" << std::endl; if(!resps.hasMore()) std::cout << "Error: No Accounts. Use the Qt-GUI or the webinterface to create an account." << std::endl; int i = 0; accounts.clear(); while(resps.hasMore()) { std::string id; std::string name; std::string location; resps.getStreamToMember() << makeKeyValueReference("id", id) << makeKeyValueReference("name", name) << makeKeyValueReference("location", location); std::cout << "[" << i << "] " << name << "(" << location << ")" << std::endl; accounts.push_back(id); i++; } } if(!ask_for_password && runstate == "waiting_account_select" && last_char >= '0' && last_char <= '9' && (last_char-'0') < accounts.size()) { std::string acc = accounts[last_char-'0']; JsonStream reqs; JsonStream resps; Request req(reqs); std::stringstream ss; Response resp(resps, ss); req.mPath.push("login"); req.mPath.push("control"); reqs << makeKeyValueReference("id", acc); reqs.switchToDeserialisation(); ApiServer::RequestId id = mApiServer->handleRequest(req, resp); waitForResponse(id); inbuf.clear(); } if(edge && ask_for_password) { std::cout << "Enter the password for key " << key_name << std::endl; } if(ask_for_password && enter_was_pressed && !inbuf.empty()) { std::cout << "TerminalApiClient: got a password" << std::endl; JsonStream reqs; JsonStream resps; Request req(reqs); std::stringstream ss; Response resp(resps, ss); req.mPath.push("password"); req.mPath.push("control"); reqs << makeKeyValueReference("password", inbuf); reqs.switchToDeserialisation(); ApiServer::RequestId id = mApiServer->handleRequest(req, resp); waitForResponse(id); inbuf.clear(); } } }
void gx_gdom_tcp_reactor::on_query_is_http_get_request() { // ЭТОТ МЕТОД ВЫПОЛНЯЕТ ОТВЕТ НА ЗАПРОС "HTTP_GET_REQUEST". В "htm" БУДЕТ СФОРМИРОВАН "HTML". // ЕСЛИ ЗАПРОС БУДЕТ СОДЕРЖАТЬ ОШИБКИ СИНТАКСИСА, КАК И ОШИБКИ СВЯЗАННЫЕ С СОСТОЯНИЕМ "GDOM", // ТО В РЕЗУЛЬТИРУЮЩИЙ "HTML" ПРОСТО ОТПРАВИТСЯ ИХ ПЕРЕЧЕНЬ. ПРИ РАБОТЕ С СЕРВЕРОМ ВОЗНИКАЕТ // ИЛЛЮЗИЯ ЧТО ЗАПРОСЫ НАПРАВЛЕНЫ В ФАЙЛОВУЮ СИСТЕМУ, НО ЭТО НЕ ТАК. ПРИ ОБРАЩЕНИИ К ФАЙЛАМ, // КАК И ПРИ ОБРАЩЕНИИ К КАТАЛОГАМ, ПРОИСХОДИТ АБСОЛЮТНО ДРУГОЕ. В ШИРОКО РАСПРОСТРАНЕННЫХ // СИСТЕМАХ, ОСНОВАНЫХ НА РАЗДАЧЕ ФАЙЛОВ, В КАТАЛОГЕ ПО ПУТИ ЗАПРОСА, НАХОДИТСЯ ФАЙЛ КОТОРЫЙ // ОПРЕДЕЛЯЕТ ЧТО ИМЕННО ВЕРНЁТСЯ ВМЕСТО ФАЙЛОВОГО СОДЕРЖИМОГО ПО ЭТОМУ ПУТИ URL С ТЕКУЩИМИ // АРГУМЕНТАМИ ЭТОГО URL. ЕСЛИ ПРЕДПОЛОЖИТЬ ЧТО ЭТО ПИТОНОВСКИЙ СКРИПТ, ШЕЛЛ СКРИПТ ИЛИ ДАЖЕ // ИСПОЛНЯЕМЫЙ ФАЙЛ, ОН ПРОСТО ВЫПОЛНЯЕТСЯ КАК ПРОЦЕСС ОПЕРАЦИОННОЙ СИСТЕМЫ С АРГУМЕНТАМИ ИЗ // ЭТОГО URL В КАЧЕСТВЕ АРГУМЕНТОВ КОМАНДНОЙ СТРОКИ. РЕЗУЛЬТАТ ВЫПОЛНЕНИЯ, ИЗ ПОТОКА ВЫВОДА // ЭТОГО ПРОЦЕССА, КОПИРУЕТСЯ В СОКЕТ ИСТОЧНИКА ЗАПРОСА. НЕ ГУСТО, НЕ ПУСТО, НО РЕЗУЛЬТАТОМ // ЭТОГО БЕСХИТРОСНОГО ПОДХОДА ЯВЛЯЕТСЯ ПОЧТИ ВЕСЬ СОВРЕМЕННЫЙ (год 2017) ВЕБ. ВО ИЗБЕЖАНИЕ // ЗЛОНАМЕРЕННОГО ВЗЛОМА ОПЕРАЦИОНКИ С ТАКИМ СЕРВЕРОМ ВСЕ, ПОТЕНЦИАЛЬНО ОПАСНЫЕ ПРОЦЕССЫ НЕ // СТАРТУЮТ НА САМОЙ ОПЕРАЦИОНКЕ, А ДЕЛЕГИРУЮТСЯ ДРУГОЙ - УДАЛЕННОЙ МАШИНЕ, ВИРТУАЛЬНОЙ ИЛИ // ЕЩЁ КАКОЙ ЛИБО МАШИНЕ, НА КОТОРОЙ ФОРМИРУЮТСЯ РЕЗУЛЬТАТЫ ЗАПРОСА, ВОЗВРАЩАЮТСЯ НА МАШИНУ // С КОТОРОЙ И БЫЛО УСТАНОВЛЕНО СОЕДИНЕНИЕ, И КОПИРУЕТСЯ В СОКЕТ ИСТОЧНИКА ЗАПРОСА. МАШИНЫ, // РАБОТА КОТОРЫХ ЗАКЛЮЧАЕТСЯ ТОЛЬКО В ТОМ, ЧТОБЫ ПЕРЕНАПРАВЛЯТЬ ЗАПРОСЫ, А ЗАТЕМ ОТДАВАТЬ // ПОЛУЧЕННЫЕ РЕЗУЛЬТАТЫ - РАУТЕР, ПРОКСИ СЕРВЕР, В КАКОМ-ТО СМЫСЛЕ И DNS СЕРВЕР - ПРОСТО // ЭЛЕМЕНТЫ МАРШРУТИЗАЦИИ ЗАПРОСОВ-ОТВЕТОВ. СОСТАВЛЯЮТ ИНФРАСТРУКТУРУ ВЕБ. ЯВЛЯЮТСЯ ОСНОВОЙ // ДЛЯ СИСТЕМ ОПТИМИЗАЦИИ ВЫПОЛНЕНИЯ ЗАПРОСОВ. ИЛИ РАСПРЕДЕЛЯЯ ЗАПРОСЫ МЕЖДУ ЭКВИВАЛЕНТНЫМИ // СЕРВЕРАМИ, ИЛИ ГРУППИРУЮЯ АБСОЛЮТНО ЭКВИВАЛЕНТНЫЕ ЗАПРОСЫ - ДЛЯ ВОЗВРАТА ИМ ВСЕМ ОДНОГО // РЕЗУЛЬТАТА, ТОЛЬКО ОДНОГО ЗАПРОСА, ИЛИ НАКАПЛИВАЮЩАЯ ПАРЫ ЗАПРОС/ОТВЕТ ДЛЯ ТОГО, ЧТОБЫ // ВООБЩЕ ИЗБЕЖАТЬ ДЕЛЕГИРОВАНИЯ ЗАПРОСА, СРАЗУ ВОЗВРАЩАЯ ОТВЕТ, ЕСЛИ ЕГО СРОК ГОДНОСТИ НЕ // ИСТЁК (REST). ДАННЫЙ СЕРВЕР НЕ ФАЙЛОВЫЙ, ИМЕЕТ СОВЕРШЕННО ДРУГУЮ ОРГАНИЗАЦИЮ, И ПРИЧИНУ // ВОЗНИКНОВЕНИЯ, НО ДОЛЖЕН ИСПОЛЬЗОВАТЬ УЖЕ СЛОЖИВШУЮСЯ ИНФРАСТРУКТУРУ ВЕБ. ЗАТОЧЕННУЮ ПОД // REST И СОСТОЯЩУЮ ИЗ МИЛЛИОНОВ ЕДИНИЦ КАБЕЛЕЙ, ОТДЕЛЬНЫХ МАШИН И ЦЕЛЫХ IT-КОМПАНИЙ. // ИТАК, // В ЧЕМ ОТЛИЧИЯ: ПУТЬ URL ЗАПРОСА, ЭТО ПУТЬ К ЭЛЕМЕНТУ МОДЕЛИ ДАННЫХ, КОТОРЫЙ РАСПОЛОЖЕН В // ПАМЯТИ ИНСТАНЦИИ УЖЕ СУЩЕСТВУЮЩЕГО ПРОЦЕССА. ВИДНА ЛИ ДАННОЙ ИНСТАНЦИИ ФАЙЛОВАЯ СИСТЕМА, // ЭТО ЕЩЁ ТОТ ВОПРОС. ДЛЯ HTML GET ЗАПРОСА, ЕСЛИ ПУТИ НЕ СУЩЕСТВУЕТ, ВОЗВРАЩАЕТСЯ СТРАНИЦА // С JSON ВЕРСИЕЙ GET ЗАПРОСА, ОПИСАНИЕМ ОШИБКИ, И СРЕДСТВОМ РУЧНОЙ НАВИГАЦИИ ПО ПУТЯМ. САМ // "НАВИГАТОР" УСТАНОВЛЕН В СОСТОЯНИЕ ПРОСМОТРА БЛИЖАЙШЕГО К ЗАПРОШЕННОМУ, НО СУЩЕСТВУЮЩЕГО // В СИСТЕМЕ ПУТИ. ЕСЛИ ПУТЬ, КАКИМ ЛИБО ОБРАЗОМ, ДОЛЖЕН ЭМУЛИРОВАТЬ ФАЙЛОВЫЕ ПУТИ, БАЗОВОЕ // ПРАВИЛО ПРИЛОЖЕНИЯ, ПРОВЕРЯТЬ НАЛИЧИЕ ТАКОГО ОТНОСИТЕЛЬНОГО ПУТИ, РАСПОЛАГАЕТСЯ ПО ПУТИ // "/file". Вот тут и должен сидеть реактор выхолащивающий систему до транспортирования байт // из файловой системы в веб. Но даже тут имеются отличия. Даже правильный путь вернёт сто, // или несколько сот первых байт файла. Если нужно больше, - повторите запрос с аргументами, // с какой позиции и сколько байт(не больше чем лимитировано в системе) нужно вернуть. Всё? // Нет не всё. Этой системе не чужд трюк с процессом, который можно запустить с аргументами // командной строки. Неужели вернулась фича цэгейи (COMMON GATEWAY INTERFACE). Нет. Совсем // другой прибамбас - это чудо запустит скрипт и получит JSON ответ, в котором будет путь к // продолжению запроса на этом-же сервере. Смысл в том, что пока не нужен был этот объект, // а это сохранёнка состояния какого-то бота в сети, то и сервис связанный с его активацией // не был нужен. Но если бот всё таки востребован, и доступ к этому боту в пределах прав // доступа для данной сессии связи, то возобновляется целый процесс его работы. Для того, // чтобы устроить это чудо, процесс, в качестве аргумента, получит ключ для поиска сессии // с сокетом ожидающим ответа. Запустит актора соответствующего типа, дождется его отклика, // передаст ему все полученные аргументы и завершится. Но вот сам инициализированный бот, // найдет сессию по ключу, и впишет туда ответ, на манер "Чё нада?". // // НАХРЕНАТОР: Ключевой алгоритм этого сервера, это обращение к инстанции, размещенной в // оперативной памяти по определенному пути. Обращение для проверки наличия, обращение для // отображения, обращение для выполнения SET или GET, обращение к дереву типов, для NEW -- // всё это "обращения по пути". Сами пути разделяются по признаку, удерживают они инстанцию // полностью созданного объекта в памяти, или не удерживают. // // "Дебильный подход к NEW" : NEW обязано проверить есть ли по этому пути объект, затем // проверить есть ли сохранение этого объекта, загрузить его, объяснить ему ситуацию __DEL__ // по этому пути, снести его сохраненки, если __DEL__ этого ещё не сделал, разместить // сохраненку пустого нового объекта указанного типа, загрузить его, разъяснить ситуацию // __NEW__. В общем геммор, если "создание" "нового" объекта не отделено от "размещения" // этого "нового" по определенному пути в системе. // // На самом деле, если объект имеет набор методов определяемый набором действий над ним в // системе, некий "SYSTEM_INTERFACE", то что он будет содержать? // __on_system_type_assigned__ // объект получил путь в пространстве типов (это как обретение себя :))) // __on_create_instance_start__ // этот метод вызывается до того, как стартует thread-строитель // это нужно для того, чтобы стартовать в параллель другие задачи и/или // распараллелить "строитель" между несколькими thread-ами, что может // существенно ускорить "строитель" включающий несколько сетевых операций // __on_create_instance_finish__ // этот метод вызывается когда thread-строитель завершен // Если объект имеет собственное мнение о том, как себя вести в новом окружении: // - Окружение, это то, что даёт каждый новый путь, а их у каждой инстанции (0..N) // И каждый путь может как удерживать инстанцию в памяти, так и предъявлять к ней свои требования. // __on_system_path_connected__ // с точки зрения формальной логики, объект получил путь (это как обретение пути :))) // __on_system_path_removed__ // с точки зрения формальной логики, объект потерял путь // Если инстанцию в памяти уже невозможно отыскать ни по какому пути, это не значит что её // удаление завершено, это значит что пора писать завещание для собственной реинкарнации в // в следующей жизни. Дело в том что не все объекты умеют сохраняться для реинкарнации. // многим достаточно типа (достаточно быть собой). Но вот обретение файлового пути, это то // что поможет инстанции, заменить своё значение по умолчанию на последнее сохраненное. // С++ отравляет мозг разработчика иллюзией, что всем инстанциям насрать на свои контейнеры. // Я есть int! - Мне насрать на мои контейнеры, массив ли это, словарь ли это, функция ли это - МНЕ ПОФИГ! // Но вот проецировать эту сагу 'int'-а на инстанции других типов в объектно-ориентированном // программировании - ЧИСТОЕ ЗЛО. // INSERT ICON - IS ONLY PREVENT SEPARETE GET FOR "favicon.ico" (DMFD). // or using "<link href=\"favicon.ico\" rel=\"icon\" type=\"image/x-icon\" />" std::ostringstream htm; // Это генерирует шапку HTML страницы для доставки результатов запроса /// TODO: void gx_gdom_tcp_reactor::html_gen_head(std::ostream& htm); // htm << "<html><head>"; htm << "<title>" << "url.path().toStdString()" << "</title>"; htm << GX_NODE_INFO_FAVICON_ICO; htm << GX_NODE_INFO_HTML_STYLE; htm << "</head><body class=\"body_style\">"; // Это дамп запроса, как его понял конвертер из HTTP GET request в JSON "HTTP_GET_REQUEST" /// TODO: void gx_gdom_tcp_reactor::html_gen_request_echo(std::ostream& htm); // htm << "<p class=\"queryHead\">" << "Query as JSON" << "</p>"; htm << "<p class=\"queryJson\">"; htm << gx::json_text_dump(p_root); htm << "</p>"; // Вот в этом месте можно заливать в "htm" ответ на запрос /// TODO: void gx_gdom_tcp_reactor::html_gen_responce request_echo(std::ostream& htm); // do { if( ! p_root ) { error( htm, "request: is not JSON" ) ; break ; } // impossible for HTTP_GET_REQUEST if( ! p_root->is_dict() ) { error( htm, "request: root is not DICT" ) ; break ; } // impossible for HTTP_GET_REQUEST gx::json* p_path = ((gx::json::DICT*)p_root)->get_item("Path"); if( ! p_path ) { error( htm, "request 'Path' field missed") ; break ; } // impossible for HTTP_GET_REQUEST gdom_try_json_path find_path_results(p_path); if( ! find_path_results.mp_gdom ) { error( htm, find_path_results.oss.str() ); } else { if( find_path_results.mp_curr->is_dict() ) { htm << "<div class=\"menu\">"; htm << (( gx::gdom::root() != find_path_results.mp_curr ) ? "ESC-Back " : " n/a " ); htm << "F1-Help F2-Type F3-View F10-Root\n"; htm << "</div>"; } } std::string s_path; std::string page_path_str; std::string page_prev_str; std::list<std::string> page_path; std::list<gx::json*>::iterator segm = find_path_results.mp_path->val.begin(); for(std::size_t i=0; i < find_path_results.current_segment_number; ++i, ++segm) { gx::json* p_path_item = *segm; if (p_path_item->is_cstr()) { page_path.push_back(((gx::json::CSTR*)p_path_item)->value); } else { page_path.push_back(gx::json_dumps(*segm)); } } if( 0 == page_path.size() ) { s_path = "[]"; page_path_str = "/"; } else { s_path+="["; page_prev_str+="/"; std::size_t path_item_number = 0; for( std::list<std::string>::iterator i = page_path.begin(); i != page_path.end(); ++i ) { path_item_number += 1; s_path += std::string("\"") + (*i) + "\","; page_path_str += "/" + (*i); if ( path_item_number < page_path.size() ) { page_prev_str += (*i) + "/"; } } s_path[s_path.size()-1] = std::string("]")[0]; page_path_str +="/"; } htm << "<div class=\"path\">"; htm << s_path << "\n"; htm << "</div>"; if ( find_path_results.mp_curr->is_dict() ) { gx::dict* p_dict = (gx::dict*)find_path_results.mp_curr; if ( gx::gdom::root() != p_dict ) { htm << "<a class=\"dict\" href=\"" << page_prev_str << "\">.." << "\n</a>"; } for(gx::dict::iterator i = p_dict->begin(); i != p_dict->end(); ++i ) { htm << "<a class=\"dict\" href=\"" << page_path_str << i->first.c_str() << "\">" << i->first.c_str() << "\n</a>"; } } //htm << "SESS" << socket()->peerName().toStdString() << ":" << socket()->peerPort() << "\n"; } while(0); // Закрываем HTML body, закрываем HTML, cоздаём HttpResponse, // Присоединяем к нему HTML и отправляем результат в сокет. htm <<"</body></html>"; std::string msg_body = htm.str(); QHttpResponseHeader resp(200, "OK"); resp.setContentLength(msg_body.size()); // response.setValue("Content-Length", message_body.size() ); //response.setValue("Status-Line", "OK"); resp.setContentType("text/html"); resp.setValue("Cache-Control","no-cache"); // response.setValue("Date", "Sun, 15 Mar 2009 05:00:48 GMT"); resp.setValue("Server", "nginx/1.21"); // TODO: is needed ?? resp.setValue("Connection", "keep-alive"); // Keep socket open QString msg = resp.toString() + msg_body.c_str(); // qDebug()<<msg[0]; qDebug()<<msg_body.c_str(); qDebug()<<msg; socket()->write(msg.toStdString().c_str()); return; }
//============================================================================= //== Main program == //============================================================================= void sim(int argc, char *argv[]) { double lambda; // Mean arrival rate (cust/sec) double mu; // Mean service rate (cust/sec) double offered_load; // Create the simulation create("sim"); // Output usage if (argc != 2) { printf("Usage: 'offered_load' - offered_load between 0 and 1 \n"); return; } offered_load = atof(argv[1]); assert((offered_load > 0.0) && (offered_load < 1.0)); // CSIM initializations Server1 = facility("Server1"); Server2 = facility("Server2"); Server3 = facility("Server3"); Server4 = facility("Server4"); Server5 = facility("Server5"); Resp_table = table("Response time table"); // Parameter initializations mu = 1.0; lambda = offered_load * (double)5; // Output begin-of-simulation banner printf("*** BEGIN SIMULATION *** \n"); // Initiate generate function and hold for SIM_TIME generate(lambda, mu); hold(SIM_TIME); // Output results printf("============================================================= \n"); printf("== *** CSIM 5 x M/M/1 queueing system simulation *** == \n"); printf("============================================================= \n"); printf("= Lambda = %6.3f cust/sec \n", lambda); printf("= Mu (for each server) = %6.3f cust/sec \n", mu); printf("============================================================= \n"); printf("= Total CPU time = %6.3f sec \n", cputime()); printf("= Total sim time = %6.3f sec \n", clock); printf("= Total completions = %ld cust \n", (completions(Server1) + completions(Server2) + completions(Server3) + completions(Server4) + completions(Server5))); printf("=------------------------------------------------------------ \n"); printf("= >>> Simulation results - \n"); printf("=------------------------------------------------------------ \n"); printf("= Utilization 1 = %6.3f %% \n", 100.0 * util(Server1)); printf("= Mean num in system 1 = %6.3f cust \n", qlen(Server1)); printf("= Mean response time 1 = %6.3f sec \n", resp(Server1)); printf("= Mean service time 1 = %6.3f sec \n", serv(Server1)); printf("= Mean throughput 1 = %6.3f cust/sec \n", tput(Server1)); printf("=------------------------------------------------------------ \n"); printf("= Utilization 2 = %6.3f %% \n", 100.0 * util(Server2)); printf("= Mean num in system 2 = %6.3f cust \n", qlen(Server2)); printf("= Mean response time 2 = %6.3f sec \n", resp(Server2)); printf("= Mean service time 2 = %6.3f sec \n", serv(Server2)); printf("= Mean throughput 2 = %6.3f cust/sec \n", tput(Server2)); printf("=------------------------------------------------------------ \n"); printf("= Utilization 3 = %6.3f %% \n", 100.0 * util(Server3)); printf("= Mean num in system 3 = %6.3f cust \n", qlen(Server3)); printf("= Mean response time 3 = %6.3f sec \n", resp(Server3)); printf("= Mean service time 3 = %6.3f sec \n", serv(Server3)); printf("= Mean throughput 3 = %6.3f cust/sec \n", tput(Server3)); printf("=------------------------------------------------------------ \n"); printf("= Utilization 4 = %6.3f %% \n", 100.0 * util(Server4)); printf("= Mean num in system 4 = %6.3f cust \n", qlen(Server4)); printf("= Mean response time 4 = %6.3f sec \n", resp(Server4)); printf("= Mean service time 4 = %6.3f sec \n", serv(Server4)); printf("= Mean throughput 4 = %6.3f cust/sec \n", tput(Server4)); printf("=------------------------------------------------------------ \n"); printf("= Utilization 5 = %6.3f %% \n", 100.0 * util(Server5)); printf("= Mean num in system 5 = %6.3f cust \n", qlen(Server5)); printf("= Mean response time 5 = %6.3f sec \n", resp(Server5)); printf("= Mean service time 5 = %6.3f sec \n", serv(Server5)); printf("= Mean throughput 5 = %6.3f cust/sec \n", tput(Server5)); printf("=------------------------------------------------------------ \n"); printf("& Table mean for response time = %6.3f sec \n", table_mean(Resp_table)); printf("============================================================= \n"); // Output end-of-simulation banner printf("*** END SIMULATION *** \n"); getchar(); }
static bool receivedQuery(Client& c, DbResponse& dbresponse, Message& m ) { bool ok = true; MSGID responseTo = m.header()->id; DbMessage d(m); QueryMessage q(d); auto_ptr< Message > resp( new Message() ); CurOp& op = *(c.curop()); shared_ptr<AssertionException> ex; try { dbresponse.exhaustNS = runQuery(m, q, op, *resp); verify( !resp->empty() ); } catch ( SendStaleConfigException& e ){ ex.reset( new SendStaleConfigException( e.getns(), e.getInfo().msg, e.getVersionReceived(), e.getVersionWanted() ) ); ok = false; } catch ( AssertionException& e ) { ex.reset( new AssertionException( e.getInfo().msg, e.getCode() ) ); ok = false; } if( ex ){ op.debug().exceptionInfo = ex->getInfo(); LOGWITHRATELIMIT { log() << "assertion " << ex->toString() << " ns:" << q.ns << " query:" << (q.query.valid() ? q.query.toString() : "query object is corrupt") << endl; if( q.ntoskip || q.ntoreturn ) log() << " ntoskip:" << q.ntoskip << " ntoreturn:" << q.ntoreturn << endl; } SendStaleConfigException* scex = NULL; if ( ex->getCode() == SendStaleConfigCode ) scex = static_cast<SendStaleConfigException*>( ex.get() ); BSONObjBuilder err; ex->getInfo().append( err ); if( scex ){ err.append( "ns", scex->getns() ); scex->getVersionReceived().addToBSON( err, "vReceived" ); scex->getVersionWanted().addToBSON( err, "vWanted" ); } BSONObj errObj = err.done(); if( scex ){ log() << "stale version detected during query over " << q.ns << " : " << errObj << endl; } else{ log() << "problem detected during query over " << q.ns << " : " << errObj << endl; } BufBuilder b; b.skip(sizeof(QueryResult)); b.appendBuf((void*) errObj.objdata(), errObj.objsize()); // todo: call replyToQuery() from here instead of this!!! see dbmessage.h QueryResult * msgdata = (QueryResult *) b.buf(); b.decouple(); QueryResult *qr = msgdata; qr->_resultFlags() = ResultFlag_ErrSet; if( scex ) qr->_resultFlags() |= ResultFlag_ShardConfigStale; qr->len = b.len(); qr->setOperation(opReply); qr->cursorId = 0; qr->startingFrom = 0; qr->nReturned = 1; resp.reset( new Message() ); resp->setData( msgdata, true ); } op.debug().responseLength = resp->header()->dataLen(); dbresponse.response = resp.release(); dbresponse.responseTo = responseTo; return ok; }
void RPCClient::net_process(const std::function<void(std::string)>& disconnect) { connected = true; uint8_t count = 0; while (true) { int content_length = -2; bool close_after_read = false; int max_read; char buf[2048]; std::string line; while (true) { std::string::size_type line_break; while ((line_break = line.find("\r\n")) == std::string::npos) { if (line.find("\r") != std::string::npos) max_read = 1; else max_read = 2; if (read_all(buf, max_read, std::chrono::seconds(10)) != max_read) return disconnect("Failed to read server response"); line.append(buf, buf + max_read); if (line.length() > 16384) return disconnect("Got header longer than 16k!"); } std::string current_line(line.substr(0, line_break)); line = line.substr(line_break + 2); if (content_length == -2) { if (current_line != std::string("HTTP/1.1 200 OK")) return disconnect("Got HTTP error message: " + asciifyString(current_line)); content_length++; } else if (current_line.length()) { std::string::size_type colon(current_line.find(':')); if (colon == std::string::npos) return disconnect("Got Bad HTTP header line: " + asciifyString(current_line)); if (current_line.compare(0, strlen("Connection: "), "Connection: ") == 0) { if (current_line.compare(strlen("Connection: "), strlen("close"), "close") == 0) close_after_read = true; else if (current_line.compare(strlen("Connection: "), strlen("keep-alive"), "keep-alive") != 0) return disconnect("Got Bad HTTP Connection header line: " + asciifyString(current_line)); } else if (current_line.compare(0, strlen("Content-Length: "), "Content-Length: ") == 0) { try { size_t endpos; content_length = std::stoi(&(current_line.c_str())[strlen("Content-Length: ")], &endpos); if (content_length < 0 || endpos != current_line.length() - strlen("Content-Length: ")) return disconnect("Got Bad HTTP Content-Length header line: " + asciifyString(current_line)); } catch (std::exception& e) { return disconnect("Got Bad HTTP Content-Length header line: " + asciifyString(current_line)); } } } else if (content_length < 0) return disconnect("Got to end of HTTP headers without a Content-Length"); else break; } if (content_length < 0 || content_length > 1024*1024*100) return disconnect("Got unreasonably large response size"); //Dumb JSON parser that mostly assumes valid (minimal-size) JSON... static const std::string expected_start("{\"result\":{"); { char resp[expected_start.length()]; if (read_all(resp, expected_start.length()) != (ssize_t)expected_start.length()) return disconnect("Failed to read response"); if (memcmp(resp, &expected_start[0], expected_start.length()) != 0) return disconnect("Got result which was not an object"); } std::vector<unsigned char> resp(content_length - expected_start.length()); if (read_all((char*)&resp[0], content_length - expected_start.length()) != content_length - (ssize_t)expected_start.length()) return disconnect("Failed to read response"); auto it = resp.begin(); //These do not move std::list<CTxMemPoolEntry> txn; //These index into txn std::vector<CTxMemPoolEntry*> vectorToSort; std::unordered_map<std::string, CTxMemPoolEntry*> hashToEntry; std::unordered_multimap<std::string, CTxMemPoolEntry*> txnWaitingOnDeps; // These are values/flags about the current status of the parser int32_t stringStart = -1, fieldValueStart = -1; std::string txHash, fieldString; long tx_size = -1; uint64_t tx_fee = -1; double tx_prio = -1; bool inTx = false, inFieldString = false, inFieldValue = false; std::unordered_set<std::string> txDeps; static const std::string expected_end("},\"error\":null,\"id\":1}\n"); while (it < resp.end() - expected_end.length()) { while ((*it == ' ') && it < resp.end() - 1) it++; switch(*it) { case '"': if (stringStart != -1) { if (!inTx) txHash = std::string(resp.begin() + stringStart, it); else if (inFieldString) fieldString = std::string(resp.begin() + stringStart, it); else if (inFieldValue) return disconnect("got string as a field value"); stringStart = -1; } else stringStart = it - resp.begin() + 1; break; case ':': if (stringStart != -1) return disconnect("Got : in a string (all strings should have been hex"); if (inFieldString) { inFieldValue = true; inFieldString = false; fieldValueStart = it - resp.begin() + 1; } else if (inFieldValue) return disconnect("Got : in an unexpected place"); break; case ',': if (stringStart != -1) return disconnect("Got , in a string (all strings should have been hex"); if (inFieldValue) { inFieldValue = false; inFieldString = true; if (fieldString == "size") { try { tx_size = std::stol(std::string(resp.begin() + fieldValueStart, it)); } catch (std::exception& e) { return disconnect("transaction size could not be parsed"); } } else if (fieldString == "fee") { try { tx_fee = uint64_t(std::stod(std::string(resp.begin() + fieldValueStart, it)) * 100000000); } catch (std::exception& e) { return disconnect("transaction value could not be parsed"); } } else if (fieldString == "currentpriority") { try { tx_prio = std::stod(std::string(resp.begin() + fieldValueStart, it)); } catch (std::exception& e) { return disconnect("transaction prio could not be parsed"); } } } else if (inTx) return disconnect("Got unexpected ,"); break; case '[': { it++; int32_t depStringStart = -1; while (*it != ']' && it < resp.end() - 1) { if (*it == '"') { if (depStringStart != -1) { txDeps.insert(std::string(resp.begin() + depStringStart, it)); depStringStart = -1; } else depStringStart = it - resp.begin() + 1; } it++; } if (*it != ']' || depStringStart != -1) return disconnect("Missing array end character (])"); break; } case '{': if (stringStart != -1) return disconnect("Got { in a string (all strings should have been hex"); else if (!inTx) { inTx = true; inFieldString = true; } else return disconnect("Got JSON object start when we weren't expecting one"); break; case '}': if (inTx) { if (inFieldValue) { inFieldValue = false; if (fieldString == "size") { try { tx_size = std::stol(std::string(resp.begin() + fieldValueStart, it)); } catch (std::exception& e) { return disconnect("transaction size could not be parsed"); } } else if (fieldString == "fee") { try { tx_fee = uint64_t(std::stod(std::string(resp.begin() + fieldValueStart, it)) * 100000000); } catch (std::exception& e) { return disconnect("transaction value could not be parsed"); } } else if (fieldString == "currentpriority") { try { tx_prio = std::stod(std::string(resp.begin() + fieldValueStart, it)); } catch (std::exception& e) { return disconnect("transaction prio could not be parsed"); } } } else return disconnect("Got unepxecpted }"); if (tx_size < 0) return disconnect("Did not get transaction size"); else if (tx_fee < 0) return disconnect("Did not get transaction fee"); else if (tx_prio < 0) return disconnect("Did not get transaction prio"); std::vector<unsigned char> hash; if (!hex_str_to_reverse_vector(txHash, hash) || hash.size() != 32) return disconnect("got bad hash"); txn.emplace_back(tx_fee, tx_size, tx_prio, hash, txDeps.size()); if (!hashToEntry.insert(std::make_pair(txHash, &txn.back())).second) return disconnect("Duplicate transaction"); if (txDeps.empty()) vectorToSort.push_back(&txn.back()); else { for (const std::string& dep : txDeps) { auto depIt = hashToEntry.find(dep); if (depIt == hashToEntry.end()) txnWaitingOnDeps.insert(std::make_pair(dep, &txn.back())); else depIt->second->setDeps.insert(&txn.back()); } } auto waitingIts = txnWaitingOnDeps.equal_range(txHash); for (auto waitingIt = waitingIts.first; waitingIt != waitingIts.second; waitingIt++) txn.back().setDeps.insert(waitingIt->second); txnWaitingOnDeps.erase(txHash); inTx = false; tx_size = -1; tx_fee = -1; txDeps.clear(); } else return disconnect("Global JSON object closed before the end"); break; } it++; } if (it != resp.end() - expected_end.length() || memcmp(&(*it), &expected_end[0], expected_end.length()) != 0) return disconnect("JSON object was not closed at the end"); if (!txnWaitingOnDeps.empty()) return disconnect("Tx depended on another one which did not exist"); std::vector<std::pair<std::vector<unsigned char>, size_t> > txn_selected; std::function<bool (const CTxMemPoolEntry* a, const CTxMemPoolEntry* b)> comp = [](const CTxMemPoolEntry* a, const CTxMemPoolEntry* b) { return a->feePerKb < b->feePerKb || (a->feePerKb == b->feePerKb && a->prio < b->prio); }; std::make_heap(vectorToSort.begin(), vectorToSort.end(), comp); uint64_t minFeePerKbSelected = 4000000000; unsigned minFeePerKbTxnCount = 0; uint64_t totalSizeSelected = 0; while (totalSizeSelected < 9*MAX_FAS_TOTAL_SIZE/10 && vectorToSort.size()) { std::pop_heap(vectorToSort.begin(), vectorToSort.end(), comp); CTxMemPoolEntry* e = vectorToSort.back(); vectorToSort.pop_back(); if (e->size <= MAX_RELAY_TRANSACTION_BYTES) { for (CTxMemPoolEntry* dep : e->setDeps) if ((--dep->reqCount) == 0) { vectorToSort.push_back(dep); std::push_heap(vectorToSort.begin(), vectorToSort.end(), comp); } txn_selected.push_back(std::make_pair(e->hash, e->size)); totalSizeSelected += e->size; if (e->feePerKb == minFeePerKbSelected) minFeePerKbTxnCount++; else if (e->feePerKb < minFeePerKbSelected) { minFeePerKbSelected = e->feePerKb; minFeePerKbTxnCount = 1; } } } unsigned minFeePerKbTxnSkipped = 0; while (vectorToSort.size()) { std::pop_heap(vectorToSort.begin(), vectorToSort.end(), comp); CTxMemPoolEntry* e = vectorToSort.back(); vectorToSort.pop_back(); if (e->feePerKb != minFeePerKbSelected) break; minFeePerKbTxnSkipped++; } if (++count == 0 && minFeePerKbTxnSkipped > 1 && minFeePerKbTxnCount > 1) printf("WARNING: Skipped %u txn while accepting %u identical-fee txn\n", minFeePerKbTxnSkipped, minFeePerKbTxnCount); txn_for_block_func(txn_selected, txn.size()); awaiting_response = false; if (close_after_read) return disconnect("Got Connection: close"); } }