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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.