emacs-erc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: bug#54458: 27.2; erc-dcc-get: Re-entering top level after C stack ov


From: J.P.
Subject: Re: bug#54458: 27.2; erc-dcc-get: Re-entering top level after C stack overflow
Date: Thu, 31 Mar 2022 23:32:12 -0700
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/29.0.50 (gnu/linux)

"J.P." <jp@neverwas.me> writes:

> BTW (cc. Fernando), the reason I simply dropped nested send attempts in
> that earlier patch was because their payloads (those 4-byte receipts)
> are only meaningful to a sender honoring "the spec" [1], which says
>
>   The sender should not continue to transmit until the recipient has
>   acknowledged all data already transmitted.
>
> IOW, there shouldn't be prohibitive wire pressure when dealing with an
> obedient sender, so we needn't worry about an outgoing receipt being
> dropped (right?). And for corner-cutting senders, either those just
> treating receipts as heartbeats and ignoring their contents or those
> never bothering to read from the socket at all, "sparse but strictly
> increasing" should always suffice, I think. If I'm wrong on either
> count, we can always add more complexity.

A quick note regarding the proposed implementation: the Qt-based
graphical client KVIrc (free software) takes an identical tack WRT
dropping instead of retrying denied sends.

>From DccRecvThread::sendAck in src/modules/dcc/DccFileTransfer.cpp [1]:

  iRet = kvi_socket_send(m_fd, (void *)(ack), ackSize);

  if(iRet == ackSize)
     return true; // everything sent

  // When downloading from a fast server using send-ahead via an
  // asymmetric link (such as the common ADSL lines) it may happen that
  // the network output queue gets saturated with ACKs. In this case the
  // network stack will refuse to send our packet and we get here.

  // We should either retry to send the ACK in a while or avoid sending
  // it at all (as with send-ahead acks aren't usually checked
  // per-packet).

  if(iRet == 0)
  {
     // We can live with this: no data has been sent at all
     // Not sending the ack and hoping that the server will not
     // stall is better than killing the connection from our side
     // anyway.
     return true;
  }

  if(iRet < 0)
  {
  // Reported error. If it's EAGAIN or EINTR then no data has been sent.

  [...]

  if((err != EAGAIN) && (err != EINTR))
  #endif //!(defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW))
        {
           // some other kind of error
           postErrorEvent(KviError::AcknowledgeError);
       return false;
        }

    return true; // no data sent: same as iRet == 0 above.
  }

So if we stick to this approach and it turns out to be inadequate, at
least we won't be alone in having fumbled.

[1] 
https://github.com/kvirc/KVIrc/blob/e4a34cb9/src/modules/dcc/DccFileTransfer.cpp#L115



reply via email to

[Prev in Thread] Current Thread [Next in Thread]