| 360 | return Host->Send(addr, data.Release(), crc32, nullptr, PP_HIGH); |
| 361 | } |
| 362 | void ProcessIncomingPackets() { |
| 363 | TVector<TGUID, TCustomAllocator<TGUID>> failedRequests; |
| 364 | for (;;) { |
| 365 | TAutoPtr<TRequest> req = Host->GetRequest(); |
| 366 | if (req.Get() == nullptr) { |
| 367 | if (!failedRequests.empty()) { |
| 368 | // we want to handle following sequence of events |
| 369 | // <- send ping |
| 370 | // -> send response over IB |
| 371 | // -> send ping response (no such request) over UDP |
| 372 | // Now if we are lucky enough we can get IB response waiting in the IB receive queue |
| 373 | // at the same time response sender will receive "send complete" from IB |
| 374 | // indeed, IB delivered message (but it was not parsed by ib_cs.cpp yet) |
| 375 | // so after receiving "send response complete" event resposne sender can legally response |
| 376 | // to pings with "no such request" |
| 377 | // but ping responses can be sent over UDP |
| 378 | // So we can run into situation with negative ping response in |
| 379 | // UDP receive queue and response waiting unprocessed in IB receive queue |
| 380 | // to check that there is no response in the IB queue we have to process IB queues |
| 381 | // so we call IBStep() |
| 382 | Host->IBStep(); |
| 383 | req = Host->GetRequest(); |
| 384 | if (req.Get() == nullptr) { |
| 385 | break; |
| 386 | } |
| 387 | } else { |
| 388 | break; |
| 389 | } |
| 390 | } |
| 391 | |
| 392 | TBlockChainIterator reqData(req->Data->GetChain()); |
| 393 | char pktType; |
| 394 | reqData.Read(&pktType, 1); |
| 395 | switch (pktType) { |
| 396 | case PKT_REQUEST: |
| 397 | case PKT_LOCAL_REQUEST: { |
| 398 | //printf("recv PKT_REQUEST or PKT_LOCAL_REQUEST\n"); |
| 399 | TGUID reqId = req->Guid; |
| 400 | TInRequestHash::iterator z = InRequests.find(reqId); |
| 401 | if (z != InRequests.end()) { |
| 402 | // oops, this request already exists! |
| 403 | // might happen if request can be stored in single packet |
| 404 | // and this packet had source IP broken during transmission and managed to pass crc checks |
| 405 | // since we already reported wrong source address for this request to the user |
| 406 | // the best thing we can do is to stop the program to avoid further complications |
| 407 | // but we just report the accident to stderr |
| 408 | fprintf(stderr, "Jackpot, same request %s received twice from %s and earlier from %s\n", |
| 409 | GetGuidAsString(reqId).c_str(), GetAddressAsString(z->second.Address).c_str(), |
| 410 | GetAddressAsString(req->Address).c_str()); |
| 411 | } else { |
| 412 | InRequests[reqId] = TInRequestState(req->Address); |
| 413 | |
| 414 | //printf("InReq %s PKT_REQUEST recv ... -> S_WAITING\n", GetGuidAsString(reqId).c_str()); |
| 415 | |
| 416 | TUdpHttpRequest* res = new TUdpHttpRequest; |
| 417 | res->ReqId = reqId; |
| 418 | res->PeerAddress = req->Address; |
| 419 | res->DataHolder = req; |
nothing calls this directly
no test coverage detected