| 685 | } |
| 686 | |
| 687 | void TUdpHost::SendData(TList<TTransferKey>* order, float deltaT1, bool needCheckAlive) { |
| 688 | for (TList<TTransferKey>::iterator z = order->begin(); z != order->end();) { |
| 689 | // pick connection to send |
| 690 | const TTransferKey& transferKey = *z; |
| 691 | TUdpOutXferHash::iterator i = SendQueue.find(transferKey); |
| 692 | if (i == SendQueue.end()) { |
| 693 | z = order->erase(z); |
| 694 | continue; |
| 695 | } |
| 696 | ++z; |
| 697 | |
| 698 | // perform sending |
| 699 | int transferId = transferKey.Id; |
| 700 | TUdpOutTransfer& xfer = i->second; |
| 701 | |
| 702 | if (!xfer.AckTracker.IsInitialized()) { |
| 703 | TIntrusivePtr<TCongestionControl> congestion = xfer.AckTracker.GetCongestionControl(); |
| 704 | Y_ASSERT(congestion.Get() != nullptr); |
| 705 | if (!congestion->IsKnownMTU()) { |
| 706 | TLameMTUDiscovery* md = congestion->GetMTUDiscovery(); |
| 707 | if (md->IsTimedOut()) { |
| 708 | congestion->SetMTU(UDP_PACKET_SIZE_SMALL); |
| 709 | } else { |
| 710 | if (md->CanSend()) { |
| 711 | SendPing(s, xfer.ToAddress, s.GetNetworkOrderPort()); |
| 712 | md->PingSent(); |
| 713 | } |
| 714 | continue; |
| 715 | } |
| 716 | } |
| 717 | // try to use large mtu, we could have selected small mtu due to connectivity problems |
| 718 | if (congestion->GetMTU() == UDP_PACKET_SIZE_SMALL || IB.Get() != nullptr) { |
| 719 | // recheck every ~50mb |
| 720 | int chkDenom = (50000000 / xfer.Data->GetSize()) | 1; |
| 721 | if ((NetAckRnd() % chkDenom) == 0) { |
| 722 | //printf("send rechecking ping\n"); |
| 723 | if (congestion->GetMTU() == UDP_PACKET_SIZE_SMALL) { |
| 724 | SendPing(s, xfer.ToAddress, s.GetNetworkOrderPort()); |
| 725 | } else { |
| 726 | SendFakePing(s, xfer.ToAddress, s.GetNetworkOrderPort()); |
| 727 | } |
| 728 | } |
| 729 | } |
| 730 | xfer.PacketSize = congestion->GetMTU(); |
| 731 | xfer.LastPacketSize = xfer.Data->GetSize() % xfer.PacketSize; |
| 732 | xfer.PacketCount = xfer.Data->GetSize() / xfer.PacketSize + 1; |
| 733 | xfer.AckTracker.SetPacketCount(xfer.PacketCount); |
| 734 | } |
| 735 | |
| 736 | xfer.AckTracker.Step(deltaT1); |
| 737 | MaxWaitTime = Min(MaxWaitTime, xfer.AckTracker.GetTimeToNextPacketTimeout()); |
| 738 | if (needCheckAlive && !xfer.AckTracker.IsAlive()) { |
| 739 | FailedSend(transferId); |
| 740 | SendQueue.erase(i); |
| 741 | continue; |
| 742 | } |
| 743 | bool sendBufferOverflow = false; |
| 744 | while (xfer.AckTracker.CanSend()) { |
nothing calls this directly
no test coverage detected