Annotation of qemu/slirp/sbuf.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1995 Danny Gasparovski.
        !             3:  * 
        !             4:  * Please read the file COPYRIGHT for the 
        !             5:  * terms and conditions of the copyright.
        !             6:  */
        !             7: 
        !             8: #include <slirp.h>
        !             9: 
        !            10: /* Done as a macro in socket.h */
        !            11: /* int
        !            12:  * sbspace(struct sockbuff *sb) 
        !            13:  * {
        !            14:  *     return SB_DATALEN - sb->sb_cc;
        !            15:  * }
        !            16:  */
        !            17: 
        !            18: void
        !            19: sbfree(sb)
        !            20:        struct sbuf *sb;
        !            21: {
        !            22:        free(sb->sb_data);
        !            23: }
        !            24: 
        !            25: void
        !            26: sbdrop(sb, num)
        !            27:        struct sbuf *sb;
        !            28:        int num; 
        !            29: {
        !            30:        /* 
        !            31:         * We can only drop how much we have
        !            32:         * This should never succeed 
        !            33:         */
        !            34:        if(num > sb->sb_cc)
        !            35:                num = sb->sb_cc;
        !            36:        sb->sb_cc -= num;
        !            37:        sb->sb_rptr += num;
        !            38:        if(sb->sb_rptr >= sb->sb_data + sb->sb_datalen)
        !            39:                sb->sb_rptr -= sb->sb_datalen;
        !            40:    
        !            41: }
        !            42: 
        !            43: void
        !            44: sbreserve(sb, size)
        !            45:        struct sbuf *sb;
        !            46:        int size;
        !            47: {
        !            48:        if (sb->sb_data) {
        !            49:                /* Already alloced, realloc if necessary */
        !            50:                if (sb->sb_datalen != size) {
        !            51:                        sb->sb_wptr = sb->sb_rptr = sb->sb_data = (char *)realloc(sb->sb_data, size);
        !            52:                        sb->sb_cc = 0;
        !            53:                        if (sb->sb_wptr)
        !            54:                           sb->sb_datalen = size;
        !            55:                        else
        !            56:                           sb->sb_datalen = 0;
        !            57:                }
        !            58:        } else {
        !            59:                sb->sb_wptr = sb->sb_rptr = sb->sb_data = (char *)malloc(size);
        !            60:                sb->sb_cc = 0;
        !            61:                if (sb->sb_wptr)
        !            62:                   sb->sb_datalen = size;
        !            63:                else
        !            64:                   sb->sb_datalen = 0;
        !            65:        }
        !            66: }
        !            67: 
        !            68: /*
        !            69:  * Try and write() to the socket, whatever doesn't get written
        !            70:  * append to the buffer... for a host with a fast net connection,
        !            71:  * this prevents an unnecessary copy of the data
        !            72:  * (the socket is non-blocking, so we won't hang)
        !            73:  */
        !            74: void
        !            75: sbappend(so, m)
        !            76:        struct socket *so;
        !            77:        struct mbuf *m;
        !            78: {
        !            79:        int ret = 0;
        !            80:        
        !            81:        DEBUG_CALL("sbappend");
        !            82:        DEBUG_ARG("so = %lx", (long)so);
        !            83:        DEBUG_ARG("m = %lx", (long)m);
        !            84:        DEBUG_ARG("m->m_len = %d", m->m_len);
        !            85:        
        !            86:        /* Shouldn't happen, but...  e.g. foreign host closes connection */
        !            87:        if (m->m_len <= 0) {
        !            88:                m_free(m);
        !            89:                return;
        !            90:        }
        !            91:        
        !            92:        /*
        !            93:         * If there is urgent data, call sosendoob
        !            94:         * if not all was sent, sowrite will take care of the rest
        !            95:         * (The rest of this function is just an optimisation)
        !            96:         */
        !            97:        if (so->so_urgc) {
        !            98:                sbappendsb(&so->so_rcv, m);
        !            99:                m_free(m);
        !           100:                sosendoob(so);
        !           101:                return;
        !           102:        }
        !           103:        
        !           104:        /*
        !           105:         * We only write if there's nothing in the buffer,
        !           106:         * ottherwise it'll arrive out of order, and hence corrupt
        !           107:         */
        !           108:        if (!so->so_rcv.sb_cc)
        !           109:           ret = send(so->s, m->m_data, m->m_len, 0);
        !           110:        
        !           111:        if (ret <= 0) {
        !           112:                /* 
        !           113:                 * Nothing was written
        !           114:                 * It's possible that the socket has closed, but
        !           115:                 * we don't need to check because if it has closed,
        !           116:                 * it will be detected in the normal way by soread()
        !           117:                 */
        !           118:                sbappendsb(&so->so_rcv, m);
        !           119:        } else if (ret != m->m_len) {
        !           120:                /*
        !           121:                 * Something was written, but not everything..
        !           122:                 * sbappendsb the rest
        !           123:                 */
        !           124:                m->m_len -= ret;
        !           125:                m->m_data += ret;
        !           126:                sbappendsb(&so->so_rcv, m);
        !           127:        } /* else */
        !           128:        /* Whatever happened, we free the mbuf */
        !           129:        m_free(m);
        !           130: }
        !           131: 
        !           132: /*
        !           133:  * Copy the data from m into sb
        !           134:  * The caller is responsible to make sure there's enough room
        !           135:  */
        !           136: void
        !           137: sbappendsb(sb, m)
        !           138:         struct sbuf *sb;
        !           139:         struct mbuf *m;
        !           140: {
        !           141:        int len, n,  nn;
        !           142:        
        !           143:        len = m->m_len;
        !           144: 
        !           145:        if (sb->sb_wptr < sb->sb_rptr) {
        !           146:                n = sb->sb_rptr - sb->sb_wptr;
        !           147:                if (n > len) n = len;
        !           148:                memcpy(sb->sb_wptr, m->m_data, n);
        !           149:        } else {
        !           150:                /* Do the right edge first */
        !           151:                n = sb->sb_data + sb->sb_datalen - sb->sb_wptr;
        !           152:                if (n > len) n = len;
        !           153:                memcpy(sb->sb_wptr, m->m_data, n);
        !           154:                len -= n;
        !           155:                if (len) {
        !           156:                        /* Now the left edge */
        !           157:                        nn = sb->sb_rptr - sb->sb_data;
        !           158:                        if (nn > len) nn = len;
        !           159:                        memcpy(sb->sb_data,m->m_data+n,nn);
        !           160:                        n += nn;
        !           161:                }
        !           162:        }
        !           163: 
        !           164:        sb->sb_cc += n;
        !           165:        sb->sb_wptr += n;
        !           166:        if (sb->sb_wptr >= sb->sb_data + sb->sb_datalen)
        !           167:                sb->sb_wptr -= sb->sb_datalen;
        !           168: }
        !           169: 
        !           170: /*
        !           171:  * Copy data from sbuf to a normal, straight buffer
        !           172:  * Don't update the sbuf rptr, this will be
        !           173:  * done in sbdrop when the data is acked
        !           174:  */
        !           175: void
        !           176: sbcopy(sb, off, len, to)
        !           177:        struct sbuf *sb;
        !           178:        int off;
        !           179:        int len;
        !           180:        char *to;
        !           181: {
        !           182:        char *from;
        !           183:        
        !           184:        from = sb->sb_rptr + off;
        !           185:        if (from >= sb->sb_data + sb->sb_datalen)
        !           186:                from -= sb->sb_datalen;
        !           187: 
        !           188:        if (from < sb->sb_wptr) {
        !           189:                if (len > sb->sb_cc) len = sb->sb_cc;
        !           190:                memcpy(to,from,len);
        !           191:        } else {
        !           192:                /* re-use off */
        !           193:                off = (sb->sb_data + sb->sb_datalen) - from;
        !           194:                if (off > len) off = len;
        !           195:                memcpy(to,from,off);
        !           196:                len -= off;
        !           197:                if (len)
        !           198:                   memcpy(to+off,sb->sb_data,len);
        !           199:        }
        !           200: }
        !           201:                

unix.superglobalmegacorp.com