Annotation of researchv8dc/sys/inet/tcp_subr.c, revision 1.1.1.1

1.1       root        1: /*     tcp_subr.c      6.1     83/07/29        */
                      2: #include "tcp.h"
                      3: #if NTCP > 0
                      4: 
                      5: #include "../h/param.h"
                      6: #include "../h/systm.h"
                      7: #include "../h/stream.h"
                      8: #include "../h/inet/mbuf.h"
                      9: #include "../h/inet/in.h"
                     10: #include "../h/inet/ip.h"
                     11: #include "../h/inet/ip_var.h"
                     12: #include "../h/inet/tcp.h"
                     13: #include "../h/inet/tcp_fsm.h"
                     14: #include "../h/inet/tcp_seq.h"
                     15: #include "../h/inet/tcp_timer.h"
                     16: #include "../h/inet/tcp_var.h"
                     17: #include "../h/inet/tcpip.h"
                     18: #include "../h/inet/socket.h"
                     19: #include "../h/inet/tcpdebug.h"
                     20: 
                     21: extern int tcp_maxseg;
                     22: 
                     23: /*
                     24:  * Create template to be used to send tcp packets on a connection.
                     25:  * Call after host entry created, allocates an mbuf and fills
                     26:  * in a skeletal tcp/ip header, minimizing the amount of work
                     27:  * necessary when the connection is used.
                     28:  */
                     29: struct tcpiphdr *
                     30: tcp_template(tp)
                     31:        struct tcpcb *tp;
                     32: {
                     33:        register struct socket *so = tp->t_socket;
                     34:        register struct mbuf *m;
                     35:        register struct tcpiphdr *n;
                     36: 
                     37:        m = m_get(M_WAIT, MT_HEADER);
                     38:        if (m == NULL)
                     39:                return (0);
                     40:        m->next = 0;
                     41:        m->wptr += sizeof (struct tcpiphdr);
                     42:        n = mtod(m, struct tcpiphdr *);
                     43:        n->ti_next = n->ti_prev = 0;
                     44:        n->ti_x1 = 0;
                     45:        n->ti_pr = 6;   /* tcp protocol number */
                     46:        n->ti_len = htons(sizeof (struct tcpiphdr) - sizeof (struct ip));
                     47:        n->ti_src = so->so_laddr;
                     48:        n->ti_dst = so->so_faddr;
                     49:        n->ti_sport = so->so_lport;
                     50:        n->ti_dport = so->so_fport;
                     51:        n->ti_seq = 0;
                     52:        n->ti_ack = 0;
                     53:        n->ti_x2 = 0;
                     54:        n->ti_off = 5;
                     55:        n->ti_flags = 0;
                     56:        n->ti_win = 0;
                     57:        n->ti_sum = 0;
                     58:        n->ti_urp = 0;
                     59:        return (n);
                     60: }
                     61: 
                     62: /*
                     63:  * Send a single message to the TCP at address specified by
                     64:  * the given TCP/IP header.  If flags==0, then we make a copy
                     65:  * of the tcpiphdr at ti and send directly to the addressed host.
                     66:  * This is used to force keep alive messages out using the TCP
                     67:  * template for a connection tp->t_template.  If flags are given
                     68:  * then we send a message back to the TCP which originated the
                     69:  * segment ti, and discard the mbuf containing it and any other
                     70:  * attached mbufs.
                     71:  *
                     72:  * In any case the ack and sequence number of the transmitted
                     73:  * segment are as specified by the parameters.
                     74:  */
                     75: tcp_respond(tp, ti, ack, seq, flags)
                     76:        struct tcpcb *tp;
                     77:        register struct tcpiphdr *ti;
                     78:        tcp_seq ack, seq;
                     79:        int flags;
                     80: {
                     81:        struct mbuf *m;
                     82:        int win = 0, tlen;
                     83: 
                     84:        if (tp) {
                     85:                win = sbrcvspace(tp->t_socket);
                     86:        }
                     87:        if (flags == 0) {
                     88:                m = m_get(M_DONTWAIT, MT_HEADER);
                     89:                if (m == NULL)
                     90:                        return;
                     91:                m->next = 0;
                     92:                m->wptr += sizeof (struct tcpiphdr) + 1;
                     93:                *mtod(m, struct tcpiphdr *) = *ti;
                     94:                ti = mtod(m, struct tcpiphdr *);
                     95:                flags = TH_ACK;
                     96:                tlen = 1;
                     97:        } else {
                     98:                m = dtom(ti);
                     99:                m_freem(m->m_next);
                    100:                m->m_next = 0;
                    101:                m->rptr = (u_char *)ti;
                    102:                m->wptr = m->rptr + sizeof (struct tcpiphdr);
                    103: #define xchg(a,b,type) { type t; t=a; a=b; b=t; }
                    104:                xchg(ti->ti_dst, ti->ti_src, u_long);
                    105:                xchg(ti->ti_dport, ti->ti_sport, u_short);
                    106: #undef xchg
                    107:                tlen = 0;
                    108:        }
                    109:        ti->ti_next = ti->ti_prev = 0;
                    110:        ti->ti_x1 = 0;
                    111:        ti->ti_len = htons((u_short)(sizeof (struct tcphdr) + tlen));
                    112:        ti->ti_seq = htonl(seq);
                    113:        ti->ti_ack = htonl(ack);
                    114:        ti->ti_x2 = 0;
                    115:        ti->ti_off = sizeof (struct tcphdr) >> 2;
                    116:        ti->ti_flags = flags;
                    117:        ti->ti_win = htons((u_short)win);
                    118:        ti->ti_urp = 0;
                    119:        ti->ti_src = htonl(ti->ti_src);
                    120:        ti->ti_dst = htonl(ti->ti_dst);
                    121:        ti->ti_sport = htons(ti->ti_sport);
                    122:        ti->ti_dport = htons(ti->ti_dport);
                    123:        ti->ti_sum = in_cksum(m, sizeof (struct tcpiphdr) + tlen);
                    124:        ((struct ip *)ti)->ip_len = sizeof (struct tcpiphdr) + tlen;
                    125:        ((struct ip *)ti)->ip_ttl = TCP_TTL;
                    126: 
                    127:        ti->ti_dst = ntohl(ti->ti_dst);
                    128:        ti->ti_src = ntohl(ti->ti_src);
                    129:        tcp_debug(ti, 1);
                    130:        tcp_ldout(m);
                    131: }
                    132: 
                    133: /*
                    134:  * Create a new TCP control block, making an
                    135:  * empty reassembly queue and hooking it to the argument
                    136:  * protocol control block.
                    137:  */
                    138: struct tcpcb *
                    139: tcp_newtcpcb(so)
                    140:        struct socket *so;
                    141: {
                    142:        register struct tcpcb *tp;
                    143:        extern struct tcpcb tcpcb[];
                    144: 
                    145:        tp = &tcpcb[so->so_dev];
                    146:        if(tp->t_template)
                    147:                (void) m_free(dtom(tp->t_template));
                    148:        bzero(tp, sizeof(struct tcpcb));
                    149:        tp->seg_next = tp->seg_prev = (struct tcpiphdr *)tp;
                    150:        /*
                    151:         * If the default maximum IP packet size is 576 bytes
                    152:         * and a standard IP header is 20 bytes, with a TCP
                    153:         * header of 20 bytes plus the options necessary to
                    154:         * upgrade it to something higher, then initialize the
                    155:         * maximum segment size to 576 - (20 + 20 + 8 + slop).
                    156:         */
                    157:        tp->t_maxseg = tcp_maxseg;      /* satisfy the rest of the world */
                    158:        tp->t_flags = 0;                /* sends options! */
                    159:        tp->t_socket = so;
                    160:        so->so_tcpcb = tp;
                    161:        return (tp);
                    162: }
                    163: 
                    164: /*
                    165:  * Drop a TCP connection.
                    166:  * If connection is synchronized,
                    167:  * then send a RST to peer.
                    168:  */
                    169: struct tcpcb *
                    170: tcp_drop(tp)
                    171:        register struct tcpcb *tp;
                    172: {
                    173: 
                    174:        if (TCPS_HAVERCVDSYN(tp->t_state)) {
                    175:                tp->t_state = TCPS_CLOSED;
                    176:                (void) tcp_output(tp);
                    177:        }
                    178:        return (tcp_close(tp));
                    179: }
                    180: 
                    181: /*
                    182:  * Close a TCP control block:
                    183:  *     discard all space held by the tcp
                    184:  *     discard internet protocol block
                    185:  *     wake up any sleepers
                    186:  */
                    187: struct tcpcb *
                    188: tcp_close(tp)
                    189:        register struct tcpcb *tp;
                    190: {
                    191:        register struct tcpiphdr *t;
                    192:        struct socket *so = tp->t_socket;
                    193:        register struct mbuf *m;
                    194: 
                    195:        if(!tp)
                    196:                panic("tcp_close");
                    197:        t = tp->seg_next;
                    198:        while (t != (struct tcpiphdr *)tp) {
                    199:                t = (struct tcpiphdr *)t->ti_next;
                    200:                m = dtom(t->ti_prev);
                    201:                remque(t->ti_prev);
                    202:                m_freem(m);
                    203:        }
                    204:        if (tp->t_template)
                    205:                (void) m_free(dtom(tp->t_template));
                    206:        tp->t_template = 0;
                    207:        if (tp->t_tcpopt)
                    208:                (void) m_free(dtom(tp->t_tcpopt));
                    209:        tp->t_tcpopt = 0;
                    210:        if (tp->t_ipopt)
                    211:                (void) m_free(dtom(tp->t_ipopt));
                    212:        tp->t_ipopt = 0;
                    213:        so->so_tcpcb = 0;
                    214:        soisdisconnected(so);
                    215:        return ((struct tcpcb *)0);
                    216: }
                    217: 
                    218: /*
                    219:  * For debugging save time event occurred, the direction of the message,
                    220:  * and the tcp header.  Then increment the pointer to the tcp
                    221:  * debug queue.
                    222:  */
                    223: int Nbugarr=SIZDEBUG;
                    224: struct tcpdebug bugarr[SIZDEBUG];      /* buffer to store the debug info in */
                    225: int tcpdbg_ind=0;                      /* index into bugarr at last entry */
                    226: 
                    227: tcp_debug(ti, code)
                    228: struct tcpiphdr *ti;
                    229: {
                    230:        bugarr[tcpdbg_ind].stamp = time;
                    231:        bugarr[tcpdbg_ind].inout = code;
                    232:        bugarr[tcpdbg_ind].savhdr = ti->ti_t;
                    233:        tcpdbg_ind = (tcpdbg_ind + 1) % SIZDEBUG;
                    234: }

unix.superglobalmegacorp.com

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