Annotation of 42BSD/sys/netinet/tcp_subr.c, revision 1.1.1.1

1.1       root        1: /*     tcp_subr.c      6.1     83/07/29        */
                      2: 
                      3: #include "../h/param.h"
                      4: #include "../h/systm.h"
                      5: #include "../h/mbuf.h"
                      6: #include "../h/socket.h"
                      7: #include "../h/socketvar.h"
                      8: #include "../h/protosw.h"
                      9: #include "../h/errno.h"
                     10: 
                     11: #include "../net/route.h"
                     12: #include "../net/if.h"
                     13: 
                     14: #include "../netinet/in.h"
                     15: #include "../netinet/in_pcb.h"
                     16: #include "../netinet/in_systm.h"
                     17: #include "../netinet/ip.h"
                     18: #include "../netinet/ip_var.h"
                     19: #include "../netinet/ip_icmp.h"
                     20: #include "../netinet/tcp.h"
                     21: #include "../netinet/tcp_fsm.h"
                     22: #include "../netinet/tcp_seq.h"
                     23: #include "../netinet/tcp_timer.h"
                     24: #include "../netinet/tcp_var.h"
                     25: #include "../netinet/tcpip.h"
                     26: 
                     27: /*
                     28:  * Tcp initialization
                     29:  */
                     30: tcp_init()
                     31: {
                     32: 
                     33:        tcp_iss = 1;            /* wrong */
                     34:        tcb.inp_next = tcb.inp_prev = &tcb;
                     35:        tcp_alpha = TCP_ALPHA;
                     36:        tcp_beta = TCP_BETA;
                     37: }
                     38: 
                     39: /*
                     40:  * Create template to be used to send tcp packets on a connection.
                     41:  * Call after host entry created, allocates an mbuf and fills
                     42:  * in a skeletal tcp/ip header, minimizing the amount of work
                     43:  * necessary when the connection is used.
                     44:  */
                     45: struct tcpiphdr *
                     46: tcp_template(tp)
                     47:        struct tcpcb *tp;
                     48: {
                     49:        register struct inpcb *inp = tp->t_inpcb;
                     50:        register struct mbuf *m;
                     51:        register struct tcpiphdr *n;
                     52: 
                     53:        m = m_get(M_WAIT, MT_HEADER);
                     54:        if (m == NULL)
                     55:                return (0);
                     56:        m->m_off = MMAXOFF - sizeof (struct tcpiphdr);
                     57:        m->m_len = sizeof (struct tcpiphdr);
                     58:        n = mtod(m, struct tcpiphdr *);
                     59:        n->ti_next = n->ti_prev = 0;
                     60:        n->ti_x1 = 0;
                     61:        n->ti_pr = IPPROTO_TCP;
                     62:        n->ti_len = htons(sizeof (struct tcpiphdr) - sizeof (struct ip));
                     63:        n->ti_src = inp->inp_laddr;
                     64:        n->ti_dst = inp->inp_faddr;
                     65:        n->ti_sport = inp->inp_lport;
                     66:        n->ti_dport = inp->inp_fport;
                     67:        n->ti_seq = 0;
                     68:        n->ti_ack = 0;
                     69:        n->ti_x2 = 0;
                     70:        n->ti_off = 5;
                     71:        n->ti_flags = 0;
                     72:        n->ti_win = 0;
                     73:        n->ti_sum = 0;
                     74:        n->ti_urp = 0;
                     75:        return (n);
                     76: }
                     77: 
                     78: /*
                     79:  * Send a single message to the TCP at address specified by
                     80:  * the given TCP/IP header.  If flags==0, then we make a copy
                     81:  * of the tcpiphdr at ti and send directly to the addressed host.
                     82:  * This is used to force keep alive messages out using the TCP
                     83:  * template for a connection tp->t_template.  If flags are given
                     84:  * then we send a message back to the TCP which originated the
                     85:  * segment ti, and discard the mbuf containing it and any other
                     86:  * attached mbufs.
                     87:  *
                     88:  * In any case the ack and sequence number of the transmitted
                     89:  * segment are as specified by the parameters.
                     90:  */
                     91: tcp_respond(tp, ti, ack, seq, flags)
                     92:        struct tcpcb *tp;
                     93:        register struct tcpiphdr *ti;
                     94:        tcp_seq ack, seq;
                     95:        int flags;
                     96: {
                     97:        struct mbuf *m;
                     98:        int win = 0, tlen;
                     99:        struct route *ro = 0;
                    100: 
                    101:        if (tp) {
                    102:                win = sbspace(&tp->t_inpcb->inp_socket->so_rcv);
                    103:                ro = &tp->t_inpcb->inp_route;
                    104:        }
                    105:        if (flags == 0) {
                    106:                m = m_get(M_DONTWAIT, MT_HEADER);
                    107:                if (m == NULL)
                    108:                        return;
                    109:                m->m_len = sizeof (struct tcpiphdr) + 1;
                    110:                *mtod(m, struct tcpiphdr *) = *ti;
                    111:                ti = mtod(m, struct tcpiphdr *);
                    112:                flags = TH_ACK;
                    113:                tlen = 1;
                    114:        } else {
                    115:                m = dtom(ti);
                    116:                m_freem(m->m_next);
                    117:                m->m_next = 0;
                    118:                m->m_off = (int)ti - (int)m;
                    119:                m->m_len = sizeof (struct tcpiphdr);
                    120: #define xchg(a,b,type) { type t; t=a; a=b; b=t; }
                    121:                xchg(ti->ti_dst.s_addr, ti->ti_src.s_addr, u_long);
                    122:                xchg(ti->ti_dport, ti->ti_sport, u_short);
                    123: #undef xchg
                    124:                tlen = 0;
                    125:        }
                    126:        ti->ti_next = ti->ti_prev = 0;
                    127:        ti->ti_x1 = 0;
                    128:        ti->ti_len = htons((u_short)(sizeof (struct tcphdr) + tlen));
                    129:        ti->ti_seq = htonl(seq);
                    130:        ti->ti_ack = htonl(ack);
                    131:        ti->ti_x2 = 0;
                    132:        ti->ti_off = sizeof (struct tcphdr) >> 2;
                    133:        ti->ti_flags = flags;
                    134:        ti->ti_win = htons((u_short)win);
                    135:        ti->ti_urp = 0;
                    136:        ti->ti_sum = in_cksum(m, sizeof (struct tcpiphdr) + tlen);
                    137:        ((struct ip *)ti)->ip_len = sizeof (struct tcpiphdr) + tlen;
                    138:        ((struct ip *)ti)->ip_ttl = TCP_TTL;
                    139:        (void) ip_output(m, (struct mbuf *)0, ro, 0);
                    140: }
                    141: 
                    142: /*
                    143:  * Create a new TCP control block, making an
                    144:  * empty reassembly queue and hooking it to the argument
                    145:  * protocol control block.
                    146:  */
                    147: struct tcpcb *
                    148: tcp_newtcpcb(inp)
                    149:        struct inpcb *inp;
                    150: {
                    151:        struct mbuf *m = m_getclr(M_DONTWAIT, MT_PCB);
                    152:        register struct tcpcb *tp;
                    153: 
                    154:        if (m == NULL)
                    155:                return ((struct tcpcb *)0);
                    156:        tp = mtod(m, struct tcpcb *);
                    157:        tp->seg_next = tp->seg_prev = (struct tcpiphdr *)tp;
                    158:        /*
                    159:         * If the default maximum IP packet size is 576 bytes
                    160:         * and a standard IP header is 20 bytes, with a TCP
                    161:         * header of 20 bytes plus the options necessary to
                    162:         * upgrade it to something higher, then initialize the
                    163:         * maximum segment size to 576 - (20 + 20 + 8 + slop).
                    164:         */
                    165:        tp->t_maxseg = 512;             /* satisfy the rest of the world */
                    166:        tp->t_flags = 0;                /* sends options! */
                    167:        tp->t_inpcb = inp;
                    168:        inp->inp_ppcb = (caddr_t)tp;
                    169:        return (tp);
                    170: }
                    171: 
                    172: /*
                    173:  * Drop a TCP connection, reporting
                    174:  * the specified error.  If connection is synchronized,
                    175:  * then send a RST to peer.
                    176:  */
                    177: struct tcpcb *
                    178: tcp_drop(tp, errno)
                    179:        register struct tcpcb *tp;
                    180:        int errno;
                    181: {
                    182:        struct socket *so = tp->t_inpcb->inp_socket;
                    183: 
                    184:        if (TCPS_HAVERCVDSYN(tp->t_state)) {
                    185:                tp->t_state = TCPS_CLOSED;
                    186:                (void) tcp_output(tp);
                    187:        }
                    188:        so->so_error = errno;
                    189:        return (tcp_close(tp));
                    190: }
                    191: 
                    192: tcp_abort(inp)
                    193:        struct inpcb *inp;
                    194: {
                    195: 
                    196:        (void) tcp_close((struct tcpcb *)inp->inp_ppcb);
                    197: }
                    198: 
                    199: /*
                    200:  * Close a TCP control block:
                    201:  *     discard all space held by the tcp
                    202:  *     discard internet protocol block
                    203:  *     wake up any sleepers
                    204:  */
                    205: struct tcpcb *
                    206: tcp_close(tp)
                    207:        register struct tcpcb *tp;
                    208: {
                    209:        register struct tcpiphdr *t;
                    210:        struct inpcb *inp = tp->t_inpcb;
                    211:        struct socket *so = inp->inp_socket;
                    212:        register struct mbuf *m;
                    213: 
                    214:        t = tp->seg_next;
                    215:        while (t != (struct tcpiphdr *)tp) {
                    216:                t = (struct tcpiphdr *)t->ti_next;
                    217:                m = dtom(t->ti_prev);
                    218:                remque(t->ti_prev);
                    219:                m_freem(m);
                    220:        }
                    221:        if (tp->t_template)
                    222:                (void) m_free(dtom(tp->t_template));
                    223:        if (tp->t_tcpopt)
                    224:                (void) m_free(dtom(tp->t_tcpopt));
                    225:        if (tp->t_ipopt)
                    226:                (void) m_free(dtom(tp->t_ipopt));
                    227:        (void) m_free(dtom(tp));
                    228:        inp->inp_ppcb = 0;
                    229:        soisdisconnected(so);
                    230:        in_pcbdetach(inp);
                    231:        return ((struct tcpcb *)0);
                    232: }
                    233: 
                    234: tcp_drain()
                    235: {
                    236: 
                    237: }
                    238: 
                    239: tcp_ctlinput(cmd, arg)
                    240:        int cmd;
                    241:        caddr_t arg;
                    242: {
                    243:        struct in_addr *sin;
                    244:        extern u_char inetctlerrmap[];
                    245: 
                    246:        if (cmd < 0 || cmd > PRC_NCMDS)
                    247:                return;
                    248:        switch (cmd) {
                    249: 
                    250:        case PRC_ROUTEDEAD:
                    251:                break;
                    252: 
                    253:        case PRC_QUENCH:
                    254:                break;
                    255: 
                    256:        /* these are handled by ip */
                    257:        case PRC_IFDOWN:
                    258:        case PRC_HOSTDEAD:
                    259:        case PRC_HOSTUNREACH:
                    260:                break;
                    261: 
                    262:        default:
                    263:                sin = &((struct icmp *)arg)->icmp_ip.ip_dst;
                    264:                in_pcbnotify(&tcb, sin, (int)inetctlerrmap[cmd], tcp_abort);
                    265:        }
                    266: }

unix.superglobalmegacorp.com

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