Annotation of cci/sys/netinet/tcp_subr.c, revision 1.1.1.2

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:  * Changes
                     29:  *     .       from Usenet: set default max seg to 536 bytes (as
                     30:  *             mentioned by POSTEL <INC-PROJECT, MAX-SEG-SIZ.NLS.14>
                     31:  *             & letter of 7 Nov 1983.
                     32:  */
                     33: /*
                     34:  * Tcp initialization
                     35:  */
                     36: tcp_init()
                     37: {
                     38: 
                     39:        tcp_iss = 1;            /* wrong */
                     40:        tcb.inp_next = tcb.inp_prev = &tcb;
                     41:        tcp_alpha = TCP_ALPHA;
                     42:        tcp_beta = TCP_BETA;
                     43: }
                     44: 
                     45: /*
                     46:  * Create template to be used to send tcp packets on a connection.
                     47:  * Call after host entry created, allocates an mbuf and fills
                     48:  * in a skeletal tcp/ip header, minimizing the amount of work
                     49:  * necessary when the connection is used.
                     50:  */
                     51: struct tcpiphdr *
                     52: tcp_template(tp)
                     53:        struct tcpcb *tp;
                     54: {
                     55:        register struct inpcb *inp = tp->t_inpcb;
                     56:        register struct mbuf *m;
                     57:        register struct tcpiphdr *n;
                     58: 
                     59:        m = m_get(M_WAIT, MT_HEADER);
                     60:        MBUFNULL(14, m);                /* for debugging */
                     61:        if (m == NULL)
                     62:                return (0);
                     63:        m->m_off = MMAXOFF - sizeof (struct tcpiphdr);
                     64:        m->m_len = sizeof (struct tcpiphdr);
                     65:        n = mtod(m, struct tcpiphdr *);
                     66:        n->ti_next = n->ti_prev = 0;
                     67:        n->ti_x1 = 0;
                     68:        n->ti_pr = IPPROTO_TCP;
                     69:        n->ti_len = htons(sizeof (struct tcpiphdr) - sizeof (struct ip));
                     70:        n->ti_src = inp->inp_laddr;
                     71:        n->ti_dst = inp->inp_faddr;
                     72:        n->ti_sport = inp->inp_lport;
                     73:        n->ti_dport = inp->inp_fport;
                     74:        n->ti_seq = 0;
                     75:        n->ti_ack = 0;
                     76:        n->ti_x2 = 0;
                     77:        n->ti_off = 5;
                     78:        n->ti_flags = 0;
                     79:        n->ti_win = 0;
                     80:        n->ti_sum = 0;
                     81:        n->ti_urp = 0;
                     82:        return (n);
                     83: }
                     84: 
                     85: /*
                     86:  * Send a single message to the TCP at address specified by
                     87:  * the given TCP/IP header.  If flags==0, then we make a copy
                     88:  * of the tcpiphdr at ti and send directly to the addressed host.
                     89:  * This is used to force keep alive messages out using the TCP
                     90:  * template for a connection tp->t_template.  If flags are given
                     91:  * then we send a message back to the TCP which originated the
                     92:  * segment ti, and discard the mbuf containing it and any other
                     93:  * attached mbufs.
                     94:  *
                     95:  * In any case the ack and sequence number of the transmitted
                     96:  * segment are as specified by the parameters.
                     97:  */
                     98: tcp_respond(tp, ti, ack, seq, flags)
                     99:        struct tcpcb *tp;
                    100:        register struct tcpiphdr *ti;
                    101:        tcp_seq ack, seq;
                    102:        int flags;
                    103: {
                    104:        struct mbuf *m;
                    105:        int win = 0, tlen;
                    106:        struct route *ro = 0;
                    107: 
                    108:        if (tp) {
                    109:                win = sbspace(&tp->t_inpcb->inp_socket->so_rcv);
                    110:                ro = &tp->t_inpcb->inp_route;
                    111:        }
                    112:        if (flags == 0) {
1.1.1.2 ! root      113: #if defined(tahoe)
        !           114:                register struct tcpiphdr *x;    /* work around compiler bug */
        !           115: #endif
1.1       root      116:                m = m_get(M_DONTWAIT, MT_HEADER);
                    117:                MBUFNULL(15, m);                /* for debugging */
                    118:                if (m == NULL)
                    119:                        return;
                    120:                m->m_len = sizeof (struct tcpiphdr) + 1;
1.1.1.2 ! root      121: #if defined(tahoe)
        !           122:                x = mtod(m, struct tcpiphdr *);
        !           123:                *x = *ti;
        !           124: #else
1.1       root      125:                *mtod(m, struct tcpiphdr *) = *ti;
1.1.1.2 ! root      126: #endif
1.1       root      127:                ti = mtod(m, struct tcpiphdr *);
                    128:                flags = TH_ACK;
                    129:                tlen = 1;
                    130:        } else {
                    131:                m = dtom(ti);
                    132:                m_freem(m->m_next);
                    133:                m->m_next = 0;
                    134:                m->m_off = (int)ti - (int)m;
                    135:                m->m_len = sizeof (struct tcpiphdr);
                    136: #define xchg(a,b,type) { type t; t=a; a=b; b=t; }
                    137:                xchg(ti->ti_dst.s_addr, ti->ti_src.s_addr, u_long);
                    138:                xchg(ti->ti_dport, ti->ti_sport, u_short);
                    139: #undef xchg
                    140:                tlen = 0;
                    141:        }
                    142:        ti->ti_next = ti->ti_prev = 0;
                    143:        ti->ti_x1 = 0;
                    144:        ti->ti_len = htons((u_short)(sizeof (struct tcphdr) + tlen));
                    145:        ti->ti_seq = htonl(seq);
                    146:        ti->ti_ack = htonl(ack);
                    147:        ti->ti_x2 = 0;
                    148:        ti->ti_off = sizeof (struct tcphdr) >> 2;
                    149:        ti->ti_flags = flags;
                    150:        ti->ti_win = htons((u_short)win);
                    151:        ti->ti_urp = 0;
                    152:        ti->ti_sum = in_cksum(m, sizeof (struct tcpiphdr) + tlen);
                    153:        ((struct ip *)ti)->ip_len = sizeof (struct tcpiphdr) + tlen;
                    154:        ((struct ip *)ti)->ip_ttl = TCP_TTL;
                    155:        (void) ip_output(m, (struct mbuf *)0, ro, 0);
                    156: }
                    157: 
                    158: /*
                    159:  * Create a new TCP control block, making an
                    160:  * empty reassembly queue and hooking it to the argument
                    161:  * protocol control block.
                    162:  */
                    163: struct tcpcb *
                    164: tcp_newtcpcb(inp)
                    165:        struct inpcb *inp;
                    166: {
                    167:        struct mbuf *m = m_getclr(M_DONTWAIT, MT_PCB);
                    168:        register struct tcpcb *tp;
                    169:        struct ifnet *ifp;
                    170:        struct ifnet *tcp_getif();
                    171:        u_short ifmss;
                    172: 
                    173:        MBUFNULL(16, m);                /* for debugging */
                    174:        if (m == NULL)
                    175:                return ((struct tcpcb *)0);
                    176:        tp = mtod(m, struct tcpcb *);
                    177:        tp->seg_next = tp->seg_prev = (struct tcpiphdr *)tp;
                    178:        /*
                    179:         * If the default maximum IP packet size is 576 bytes
                    180:         * and a standard IP header is 20 bytes, with a TCP
                    181:         * header of 20 bytes plus the options necessary to
                    182:         * upgrade it to something higher, then initialize the
                    183:         * maximum segment size to 576 - (20 + 20 + 8 + slop).
                    184:         */
                    185:        tp->t_maxseg = 512;             /* satisfy the rest of the world */
                    186:        tp->t_flags = 0;                /* sends options! */
                    187:        tp->t_inpcb = inp;
                    188:        inp->inp_ppcb = (caddr_t)tp;
                    189:        return (tp);
                    190: }
                    191: 
                    192: /*
                    193:  * Drop a TCP connection, reporting
                    194:  * the specified error.  If connection is synchronized,
                    195:  * then send a RST to peer.
                    196:  */
                    197: struct tcpcb *
                    198: tcp_drop(tp, errno)
                    199:        register struct tcpcb *tp;
                    200:        int errno;
                    201: {
                    202:        struct socket *so = tp->t_inpcb->inp_socket;
                    203: 
                    204:        if (TCPS_HAVERCVDSYN(tp->t_state)) {
                    205:                tp->t_state = TCPS_CLOSED;
                    206:                (void) tcp_output(tp);
                    207:        }
                    208:        so->so_error = errno;
                    209:        return (tcp_close(tp));
                    210: }
                    211: 
                    212: tcp_abort(inp)
                    213:        struct inpcb *inp;
                    214: {
                    215: #ifdef NET_PERF
                    216:        printf("tcp_abort(local addr:%lx,%x, remote addr:%lx,%x)\n",
                    217:                inp->inp_faddr.s_addr, inp->inp_fport,
                    218:                inp->inp_laddr.s_addr, inp->inp_lport);
                    219: #endif
                    220: 
                    221:        (void) tcp_close((struct tcpcb *)inp->inp_ppcb);
                    222: }
                    223: 
                    224: /*
                    225:  * Close a TCP control block:
                    226:  *     discard all space held by the tcp
                    227:  *     discard internet protocol block
                    228:  *     wake up any sleepers
                    229:  */
                    230: struct tcpcb *
                    231: tcp_close(tp)
                    232:        register struct tcpcb *tp;
                    233: {
                    234:        register struct tcpiphdr *t;
                    235:        struct inpcb *inp = tp->t_inpcb;
                    236:        struct socket *so = inp->inp_socket;
                    237:        register struct mbuf *m;
                    238: 
                    239:        t = tp->seg_next;
                    240:        while (t != (struct tcpiphdr *)tp) {
                    241:                t = (struct tcpiphdr *)t->ti_next;
                    242:                m = dtom(t->ti_prev);
                    243:                remque(t->ti_prev);
                    244:                m_freem(m);
                    245:        }
                    246:        if (tp->t_template)
                    247:                (void) m_free(dtom(tp->t_template));
                    248:        if (tp->t_tcpopt)
                    249:                (void) m_free(dtom(tp->t_tcpopt));
                    250:        if (tp->t_ipopt)
                    251:                (void) m_free(dtom(tp->t_ipopt));
                    252:        (void) m_free(dtom(tp));
                    253:        inp->inp_ppcb = 0;
                    254:        soisdisconnected(so);
                    255:        in_pcbdetach(inp);
                    256:        return ((struct tcpcb *)0);
                    257: }
                    258: 
                    259: tcp_drain()
                    260: {
                    261: 
                    262: }
                    263: 
                    264: tcp_ctlinput(cmd, arg)
                    265:        int cmd;
                    266:        caddr_t arg;
                    267: {
                    268:        struct in_addr *sin;
                    269:        extern u_char inetctlerrmap[];
                    270: 
                    271:        if (cmd < 0 || cmd > PRC_NCMDS)
                    272:                return;
                    273:        switch (cmd) {
                    274: 
                    275:        case PRC_ROUTEDEAD:
                    276:                break;
                    277: 
                    278:        case PRC_QUENCH:
                    279:                break;
                    280: 
                    281:        /* these are handled by ip */
                    282:        case PRC_IFDOWN:
                    283:        case PRC_HOSTDEAD:
                    284:        case PRC_HOSTUNREACH:
                    285:                break;
                    286: 
                    287:        default:
                    288:                sin = &((struct icmp *)arg)->icmp_ip.ip_dst;
                    289:                in_pcbnotify(&tcb, sin, (int)inetctlerrmap[cmd], tcp_abort);
                    290:        }
                    291: }
                    292: /*
                    293:  * Given a tcpcb, find the route associated with tcpcb, then the
                    294:  * interface through which packets are sent.
                    295:  */
                    296: struct ifnet *
                    297: tcp_getif(tp)
                    298: struct tcpcb *tp;
                    299: {
                    300:        register struct route   *ro;
                    301:        register struct ifnet   *ifp;
                    302:        struct  route   iproute;
                    303:        struct  in_addr faddr;
                    304:        
                    305:        ro = &iproute;
                    306:        bzero((caddr_t)ro, sizeof(*ro));
                    307:        ro->ro_dst.sa_family = AF_INET;
                    308:        faddr = tp->t_inpcb->inp_faddr;
                    309:        if (faddr.s_addr == 0)
                    310:                return((struct ifnet *)0);
                    311: 
                    312:        ((struct sockaddr_in *) &iproute.ro_dst)->sin_addr = faddr;
                    313:        rtalloc(ro);
                    314:        if ((ro->ro_rt == 0) || (ifp = ro->ro_rt->rt_ifp) == 0)
                    315:                return((struct ifnet *)0);
                    316:        rtfree(ro->ro_rt);
                    317:        return (ifp);
                    318: }
                    319:        

unix.superglobalmegacorp.com

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