Esempio n. 1
0
/*
 * Try and write() to the socket, whatever doesn't get written
 * append to the buffer... for a host with a fast net connection,
 * this prevents an unnecessary copy of the data
 * (the socket is non-blocking, so we won't hang)
 */
void
sbappend(struct socket *so, struct mbuf *m)
{
	int ret = 0;

	DEBUG_CALL("sbappend");
	DEBUG_ARG("so = %lx", (long)so);
	DEBUG_ARG("m = %lx", (long)m);
	DEBUG_ARG("m->m_len = %d", m->m_len);

	/* Shouldn't happen, but...  e.g. foreign host closes connection */
	if (m->m_len <= 0) {
		m_free(m);
		return;
	}

	/*
	 * If there is urgent data, call sosendoob
	 * if not all was sent, sowrite will take care of the rest
	 * (The rest of this function is just an optimisation)
	 */
	if (so->so_urgc) {
		sbappendsb(&so->so_rcv, m);
		m_free(m);
		sosendoob(so);
		return;
	}

	/*
	 * We only write if there's nothing in the buffer,
	 * ottherwise it'll arrive out of order, and hence corrupt
	 */
	if (!so->so_rcv.sb_cc)
	   ret = send(so->s, m->m_data, m->m_len, 0);

	if (ret <= 0) {
		/*
		 * Nothing was written
		 * It's possible that the socket has closed, but
		 * we don't need to check because if it has closed,
		 * it will be detected in the normal way by soread()
		 */
		sbappendsb(&so->so_rcv, m);
	} else if (ret != m->m_len) {
		/*
		 * Something was written, but not everything..
		 * sbappendsb the rest
		 */
		m->m_len -= ret;
		m->m_data += ret;
		sbappendsb(&so->so_rcv, m);
	} /* else */
	/* Whatever happened, we free the mbuf */
	m_free(m);
}
/*
 * Try and write() to the socket, whatever doesn't get written
 * append to the buffer... for a host with a fast net connection,
 * this prevents an unnecessary copy of the data
 * (the socket is non-blocking, so we won't hang)
 */
void
sbappend(PNATState pData, struct socket *so, struct mbuf *m)
{
    int ret = 0;
    int mlen = 0;

    STAM_PROFILE_START(&pData->StatIOSBAppend_pf, a);
    LogFlow(("sbappend: so = %lx, m = %lx, m->m_len = %d\n", (long)so, (long)m, m ? m->m_len : 0));

    STAM_COUNTER_INC(&pData->StatIOSBAppend);
    /* Shouldn't happen, but...  e.g. foreign host closes connection */
    mlen = m_length(m, NULL);
    if (mlen <= 0)
    {
        STAM_COUNTER_INC(&pData->StatIOSBAppend_zm);
        goto done;
    }

    /*
     * If there is urgent data, call sosendoob
     * if not all was sent, sowrite will take care of the rest
     * (The rest of this function is just an optimisation)
     */
    if (so->so_urgc)
    {
        sbappendsb(pData, &so->so_rcv, m);
        m_freem(pData, m);
        sosendoob(so);
        return;
    }

    /*
     * We only write if there's nothing in the buffer,
     * otherwise it'll arrive out of order, and hence corrupt
     */
    if (so->so_rcv.sb_cc == 0)
    {
        caddr_t buf = NULL;

        if (m->m_next)
        {
            buf = RTMemAlloc(mlen);
            if (buf == NULL)
            {
                ret = 0;
                goto no_sent;
            }
            m_copydata(m, 0, mlen, buf);
        }
        else
            buf = mtod(m, char *);

        ret = send(so->s, buf, mlen, 0);

        if (m->m_next)
            RTMemFree(buf);
    }
Esempio n. 3
0
/*
 * Try and write() to the socket, whatever doesn't get written
 * append to the buffer... for a host with a fast net connection,
 * this prevents an unnecessary copy of the data
 * (the socket is non-blocking, so we won't hang)
 */
void
sbappend(PNATState pData, struct socket *so, struct mbuf *m)
{
    int ret = 0;
    int mlen = 0;
    caddr_t buf = NULL;

    STAM_PROFILE_START(&pData->StatIOSBAppend_pf, a);
    LogFlow(("sbappend: so = %lx, m = %lx, m->m_len = %d\n", (long)so, (long)m, m ? m->m_len : 0));

    STAM_COUNTER_INC(&pData->StatIOSBAppend);
    /* Shouldn't happen, but...  e.g. foreign host closes connection */
    mlen = m_length(m, NULL);
    if (mlen <= 0)
    {
        STAM_COUNTER_INC(&pData->StatIOSBAppend_zm);
        goto done;
    }

    /*
     * If there is urgent data, call sosendoob
     * if not all was sent, sowrite will take care of the rest
     * (The rest of this function is just an optimisation)
     */
    if (so->so_urgc)
    {
        sbappendsb(pData, &so->so_rcv, m);
        m_freem(pData, m);
        sosendoob(so);
        return;
    }

    /*
     * We only write if there's nothing in the buffer,
     * ottherwise it'll arrive out of order, and hence corrupt
     */
    if (m->m_next)
    {
        buf = RTMemAlloc(mlen);
        if (buf == NULL)
        {
            ret = 0;
            goto no_sent;
        }
        m_copydata(m, 0, mlen, buf);
    }
    else
        buf = mtod(m, char *);

    if(!so->so_rcv.sb_cc)
        ret = send(so->s, buf, mlen, 0);

    if (m->m_next)
        RTMemFree(buf);
no_sent:

    if (ret <= 0)
    {
        STAM_COUNTER_INC(&pData->StatIOSBAppend_wf);
        /*
         * Nothing was written
         * It's possible that the socket has closed, but
         * we don't need to check because if it has closed,
         * it will be detected in the normal way by soread()
         */
        sbappendsb(pData, &so->so_rcv, m);
        STAM_PROFILE_STOP(&pData->StatIOSBAppend_pf_wf, a);
        goto done;
    }
    else if (ret != mlen)
    {
        STAM_COUNTER_INC(&pData->StatIOSBAppend_wp);
        /*
         * Something was written, but not everything..
         * sbappendsb the rest
         */
        m_adj(m, ret);
        sbappendsb(pData, &so->so_rcv, m);
        STAM_PROFILE_STOP(&pData->StatIOSBAppend_pf_wp, a);
        goto done;
    } /* else */
    /* Whatever happened, we free the mbuf */
    STAM_COUNTER_INC(&pData->StatIOSBAppend_wa);
    STAM_PROFILE_STOP(&pData->StatIOSBAppend_pf_wa, a);
done:
    m_freem(pData, m);
}