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

unix.superglobalmegacorp.com

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