Annotation of qemu/slirp/sbuf.c, revision 1.1.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