| 353 | } |
| 354 | |
| 355 | void ProcessIncomingPackets() { |
| 356 | TVector<TGUID> failedRequests; |
| 357 | for (;;) { |
| 358 | TAutoPtr<TRequest> req = Host_->GetRequest(); |
| 359 | if (req.Get() == nullptr) |
| 360 | break; |
| 361 | |
| 362 | TBlockChainIterator reqData(req->Data->GetChain()); |
| 363 | char pktType; |
| 364 | reqData.Read(&pktType, 1); |
| 365 | switch (pktType) { |
| 366 | case PKT_REQUEST: |
| 367 | case PKT_LOCAL_REQUEST: { |
| 368 | TGUID reqId = req->Guid; |
| 369 | TInRequestHash::iterator z = InRequests_.find(reqId); |
| 370 | if (z != InRequests_.end()) { |
| 371 | // oops, this request already exists! |
| 372 | // might happen if request can be stored in single packet |
| 373 | // and this packet had source IP broken during transmission and managed to pass crc checks |
| 374 | // since we already reported wrong source address for this request to the user |
| 375 | // the best thing we can do is to stop the program to avoid further complications |
| 376 | // but we just report the accident to stderr |
| 377 | fprintf(stderr, "Jackpot, same request %s received twice from %s and earlier from %s\n", |
| 378 | GetGuidAsString(reqId).c_str(), GetAddressAsString(z->second.Address).c_str(), |
| 379 | GetAddressAsString(req->Address).c_str()); |
| 380 | } else { |
| 381 | InRequests_[reqId] = TInRequestState(req->Address); |
| 382 | EventCollector_->AddRequest(new TUdpHttpRequest(req, reqId, req->Address)); |
| 383 | } |
| 384 | } break; |
| 385 | case PKT_PING: { |
| 386 | TGUID guid; |
| 387 | reqData.Read(&guid, sizeof(guid)); |
| 388 | bool ok = InRequests_.find(guid) != InRequests_.end(); |
| 389 | TAutoPtr<TRopeDataPacket> ms = new TRopeDataPacket; |
| 390 | ms->Write((char)PKT_PING_RESPONSE); |
| 391 | ms->Write(guid); |
| 392 | ms->Write(ok); |
| 393 | SendWithHighPriority(req->Address, ms.Release()); |
| 394 | } break; |
| 395 | case PKT_PING_RESPONSE: { |
| 396 | TGUID guid; |
| 397 | bool ok; |
| 398 | reqData.Read(&guid, sizeof(guid)); |
| 399 | reqData.Read(&ok, sizeof(ok)); |
| 400 | TOutRequestHash::iterator i = OutRequests_.find(guid); |
| 401 | if (i == OutRequests_.end()) |
| 402 | ; //Y_ASSERT(0); // actually possible with some packet orders |
| 403 | else { |
| 404 | if (!ok) { |
| 405 | // can not delete request at this point |
| 406 | // since we can receive failed ping and response at the same moment |
| 407 | // consider sequence: client sends ping, server sends response |
| 408 | // and replies false to ping as reply is sent |
| 409 | // we can not receive failed ping_response earlier then response itself |
| 410 | // but we can receive them simultaneously |
| 411 | failedRequests.push_back(guid); |
| 412 | } else { |
nothing calls this directly
no test coverage detected