Exemple #1
0
/** Try to send a buffer to a client, queueing it if needed.
 * @param[in,out] to Client to send message to.
 * @param[in] buf Message to send.
 * @param[in] prio If non-zero, send as high priority.
 */
void send_buffer(struct Client* to, struct MsgBuf* buf, int prio)
{
  assert(0 != to);
  assert(0 != buf);

  if (cli_from(to))
    to = cli_from(to);

  if (!can_send(to))
    /*
     * This socket has already been marked as dead
     */
    return;

  if (MsgQLength(&(cli_sendQ(to))) > get_sendq(to)) {
    if (IsServer(to))
      sendto_opmask(0, SNO_OLDSNO, "Max SendQ limit exceeded for %C: %zu > %zu",
                    to, MsgQLength(&(cli_sendQ(to))), get_sendq(to));
    dead_link(to, "Max sendQ exceeded");
    return;
  }

  Debug((DEBUG_SEND, "Sending [%p] to %s", buf, cli_name(to)));

#if defined(USE_SSL)
  if (cli_socket(to).s_ssl)
      prio = 0;
#endif

  msgq_add(&(cli_sendQ(to)), buf, prio);
  client_add_sendq(cli_connect(to), &send_queues);
  update_write(to);

  /*
   * Update statistics. The following is slightly incorrect
   * because it counts messages even if queued, but bytes
   * only really sent. Queued bytes get updated in SendQueued.
   */
  ++(cli_sendM(to));
  ++(cli_sendM(&me));
  /*
   * This little bit is to stop the sendQ from growing too large when
   * there is no need for it to. Thus we call send_queued() every time
   * 2k has been added to the queue since the last non-fatal write.
   * Also stops us from deliberately building a large sendQ and then
   * trying to flood that link with data (possible during the net
   * relinking done by servers with a large load).
   */
  if (MsgQLength(&(cli_sendQ(to))) / 1024 > cli_lastsq(to))
    send_queued(to);
}
Exemple #2
0
unsigned abcsp_sendmsg(ABCSP_TXMSG *msg, unsigned chan, unsigned rel)
{
        TXMSG *m;

        /* Reject all traffic if the choke is applied.

        BCSP-LE messages are transmitted from code below this entry point.

        The choke should be applied at the "mux" layer.  Applying it here
        means that if the choke is turned on while messages are queued for
        transmission then those messages will drain out.  This is strictly
        incorrect, but this won't harm any real system as the choke is only
        set TRUE by abcsp library init, so any peer is going to see
        disrupted traffic for a while anyway.  (Ideally, bcsp-le messages
        from here will tell the peer that we've restarted, so it should
        reinit and rechoke.) */

        if(abcsp_txrx.choke) {
                ABCSP_EVENT(ABCSP_EVT_TX_CHOKE_DISCARD);
                return(0);
                }

        /* Parameter sanity checks. */
        if(rel > 1 || chan < 2 || chan > 15 || msg == (ABCSP_TXMSG*)(NULL))
                return(0);

        /* We queue enough reliable messages to fill the WINSIZE window. */
        if(rel && msgq_len(relq) >= ABCSP_TXWINSIZE) {
                ABCSP_EVENT(ABCSP_EVT_TX_WINDOW_FULL_DISCARD);
                return(0);
                }

        /* Package the message. */
        if((m = ZNEW(TXMSG)) == (TXMSG*)(NULL))
                return(0);
        m->m = msg;
        m->chan = chan;

        if(rel) {
                /* We've already checked the reliable queue has room. */
                m->seq = msgq_txseq;
                msgq_txseq = incrmod8(msgq_txseq);
                msgq_add(&relq, m);
                }
        else {
                /* The unreliable channel is biased towards supporting
                sco, for which the data has to be fresh.  The queue
                holds only one message, so we displace any message that's
                already in the queue. */

                (void) msgq_pop_destroy(&unrelq);

                msgq_add(&unrelq, m);
                }

        /* Tell external code that it needs to call abcsp_pumptxmsgs(). */
        ABCSP_REQ_PUMPTXMSGS();

        /* Report message accepted. */
        return(1);
}