Annotation of kernel/bsd/netiso/tuba_usrreq.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.1 (the "License").  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License.
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: 
                     25: /*
                     26:  * Copyright (c) 1992, 1993
                     27:  *     The Regents of the University of California.  All rights reserved.
                     28:  *
                     29:  * Redistribution and use in source and binary forms, with or without
                     30:  * modification, are permitted provided that the following conditions
                     31:  * are met:
                     32:  * 1. Redistributions of source code must retain the above copyright
                     33:  *    notice, this list of conditions and the following disclaimer.
                     34:  * 2. Redistributions in binary form must reproduce the above copyright
                     35:  *    notice, this list of conditions and the following disclaimer in the
                     36:  *    documentation and/or other materials provided with the distribution.
                     37:  * 3. All advertising materials mentioning features or use of this software
                     38:  *    must display the following acknowledgement:
                     39:  *     This product includes software developed by the University of
                     40:  *     California, Berkeley and its contributors.
                     41:  * 4. Neither the name of the University nor the names of its contributors
                     42:  *    may be used to endorse or promote products derived from this software
                     43:  *    without specific prior written permission.
                     44:  *
                     45:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     46:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     47:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     48:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     49:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     50:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     51:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     52:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     53:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     54:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     55:  * SUCH DAMAGE.
                     56:  *
                     57:  *     @(#)tuba_usrreq.c       8.1 (Berkeley) 6/10/93
                     58:  */
                     59: 
                     60: #include <sys/param.h>
                     61: #include <sys/systm.h>
                     62: #include <sys/malloc.h>
                     63: #include <sys/mbuf.h>
                     64: #include <sys/socket.h>
                     65: #include <sys/socketvar.h>
                     66: #include <sys/protosw.h>
                     67: #include <sys/errno.h>
                     68: #include <sys/stat.h>
                     69: 
                     70: #include <net/if.h>
                     71: #include <net/route.h>
                     72: 
                     73: #include <netinet/in.h>
                     74: #include <netinet/in_systm.h>
                     75: #include <netinet/ip.h>
                     76: #include <netinet/in_pcb.h>
                     77: #include <netinet/ip_var.h>
                     78: #include <netinet/tcp.h>
                     79: #include <netinet/tcp_fsm.h>
                     80: #include <netinet/tcp_seq.h>
                     81: #include <netinet/tcp_timer.h>
                     82: #include <netinet/tcp_var.h>
                     83: #include <netinet/tcpip.h>
                     84: #include <netinet/tcp_debug.h>
                     85: 
                     86: #include <netiso/argo_debug.h>
                     87: #include <netiso/iso.h>
                     88: #include <netiso/clnp.h>
                     89: #include <netiso/iso_pcb.h>
                     90: #include <netiso/iso_var.h>
                     91: #include <netiso/tuba_table.h>
                     92: /*
                     93:  * TCP protocol interface to socket abstraction.
                     94:  */
                     95: extern char *tcpstates[];
                     96: extern struct inpcb tuba_inpcb;
                     97: extern struct isopcb tuba_isopcb;
                     98: 
                     99: /*
                    100:  * Process a TCP user request for TCP tb.  If this is a send request
                    101:  * then m is the mbuf chain of send data.  If this is a timer expiration
                    102:  * (called from the software clock routine), then timertype tells which timer.
                    103:  */
                    104: /*ARGSUSED*/
                    105: tuba_usrreq(so, req, m, nam, control)
                    106:        struct socket *so;
                    107:        int req;
                    108:        struct mbuf *m, *nam, *control;
                    109: {
                    110:        register struct inpcb *inp;
                    111:        register struct isopcb *isop;
                    112:        register struct tcpcb *tp;
                    113:        int s;
                    114:        int error = 0;
                    115:        int ostate;
                    116:        struct sockaddr_iso *siso;
                    117: 
                    118:        if (req == PRU_CONTROL)
                    119:                return (iso_control(so, (int)m, (caddr_t)nam,
                    120:                        (struct ifnet *)control));
                    121: 
                    122:        s = splnet();
                    123:        inp = sotoinpcb(so);
                    124:        /*
                    125:         * When a TCP is attached to a socket, then there will be
                    126:         * a (struct inpcb) pointed at by the socket, and this
                    127:         * structure will point at a subsidary (struct tcpcb).
                    128:         */
                    129:        if (inp == 0  && req != PRU_ATTACH) {
                    130:                splx(s);
                    131:                return (EINVAL);                /* XXX */
                    132:        }
                    133:        if (inp) {
                    134:                tp = intotcpcb(inp);
                    135:                if (tp == 0)
                    136:                        panic("tuba_usrreq");
                    137:                ostate = tp->t_state;
                    138:                isop = (struct isopcb *)tp->t_tuba_pcb;
                    139:                if (isop == 0)
                    140:                        panic("tuba_usrreq 2");
                    141:        } else
                    142:                ostate = 0;
                    143:        switch (req) {
                    144: 
                    145:        /*
                    146:         * TCP attaches to socket via PRU_ATTACH, reserving space,
                    147:         * and an internet control block.  We also need to
                    148:         * allocate an isopcb and separate the control block from
                    149:         * tcp/ip ones.
                    150:         */
                    151:        case PRU_ATTACH:
                    152:                if (error = iso_pcballoc(so, &tuba_isopcb))
                    153:                        break;
                    154:                isop = (struct isopcb *)so->so_pcb;
                    155:                so->so_pcb = 0;
                    156:                if (error = tcp_usrreq(so, req, m, nam, control)) {
                    157:                        isop->isop_socket = 0;
                    158:                        iso_pcbdetach(isop);
                    159:                } else {
                    160:                        inp = sotoinpcb(so);
                    161:                        remque(inp);
                    162:                        insque(inp, &tuba_inpcb);
                    163:                        inp->inp_head = &tuba_inpcb;
                    164:                        tp = intotcpcb(inp);
                    165:                        if (tp == 0)
                    166:                                panic("tuba_usrreq 3");
                    167:                        tp->t_tuba_pcb = (caddr_t) isop;
                    168:                }
                    169:                goto notrace;
                    170: 
                    171:        /*
                    172:         * PRU_DETACH detaches the TCP protocol from the socket.
                    173:         * If the protocol state is non-embryonic, then can't
                    174:         * do this directly: have to initiate a PRU_DISCONNECT,
                    175:         * which may finish later; embryonic TCB's can just
                    176:         * be discarded here.
                    177:         */
                    178:        case PRU_DETACH:
                    179:                if (tp->t_state > TCPS_LISTEN)
                    180:                        tp = tcp_disconnect(tp);
                    181:                else
                    182:                        tp = tcp_close(tp);
                    183:                if (tp == 0)
                    184:                        tuba_pcbdetach(isop);
                    185:                break;
                    186: 
                    187:        /*
                    188:         * Give the socket an address.
                    189:         */
                    190:        case PRU_BIND:
                    191:                siso = mtod(nam, struct sockaddr_iso *);
                    192:                if (siso->siso_tlen && siso->siso_tlen != 2) {
                    193:                        error = EINVAL;
                    194:                        break;
                    195:                }
                    196:                if ((error = iso_pcbbind(isop, nam)) || 
                    197:                    (siso = isop->isop_laddr) == 0)
                    198:                        break;
                    199:                bcopy(TSEL(siso), &inp->inp_lport, 2);
                    200:                if (siso->siso_nlen &&
                    201:                    !(inp->inp_laddr.s_addr = tuba_lookup(siso, M_WAITOK)))
                    202:                        error = ENOBUFS;
                    203:                break;
                    204: 
                    205:        /*
                    206:         * Prepare to accept connections.
                    207:         */
                    208:        case PRU_CONNECT:
                    209:        case PRU_LISTEN:
                    210:                if (inp->inp_lport == 0 &&
                    211:                    (error = iso_pcbbind(isop, (struct mbuf *)0)))
                    212:                        break;
                    213:                bcopy(TSEL(isop->isop_laddr), &inp->inp_lport, 2);
                    214:                if (req == PRU_LISTEN) {
                    215:                        tp->t_state = TCPS_LISTEN;
                    216:                        break;
                    217:                }
                    218:        /*FALLTHROUGH*/
                    219:        /*
                    220:         * Initiate connection to peer.
                    221:         * Create a template for use in transmissions on this connection.
                    222:         * Enter SYN_SENT state, and mark socket as connecting.
                    223:         * Start keep-alive timer, and seed output sequence space.
                    224:         * Send initial segment on connection.
                    225:         */
                    226:        /* case PRU_CONNECT: */
                    227:                if (error = iso_pcbconnect(isop, nam))
                    228:                        break;
                    229:                if ((siso = isop->isop_laddr) && siso->siso_nlen > 1)
                    230:                        siso->siso_data[siso->siso_nlen - 1] = ISOPROTO_TCP;
                    231:                else
                    232:                        panic("tuba_usrreq: connect");
                    233:                siso = mtod(nam, struct sockaddr_iso *);
                    234:                if (!(inp->inp_faddr.s_addr = tuba_lookup(siso, M_WAITOK))) {
                    235:                unconnect:
                    236:                        iso_pcbdisconnect(isop);
                    237:                        error = ENOBUFS;
                    238:                        break;
                    239:                }
                    240:                bcopy(TSEL(isop->isop_faddr), &inp->inp_fport, 2);
                    241:                if (inp->inp_laddr.s_addr == 0 &&
                    242:                     (inp->inp_laddr.s_addr = 
                    243:                            tuba_lookup(isop->isop_laddr, M_WAITOK)) == 0)
                    244:                        goto unconnect;
                    245:                if ((tp->t_template = tcp_template(tp)) == 0)
                    246:                        goto unconnect;
                    247:                soisconnecting(so);
                    248:                tcpstat.tcps_connattempt++;
                    249:                tp->t_state = TCPS_SYN_SENT;
                    250:                tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
                    251:                tp->iss = tcp_iss; tcp_iss += TCP_ISSINCR/2;
                    252:                tcp_sendseqinit(tp);
                    253:                error = tcp_output(tp);
                    254:                tuba_refcnt(isop, 1);
                    255:                break;
                    256: 
                    257:        /*
                    258:         * Initiate disconnect from peer.
                    259:         * If connection never passed embryonic stage, just drop;
                    260:         * else if don't need to let data drain, then can just drop anyways,
                    261:         * else have to begin TCP shutdown process: mark socket disconnecting,
                    262:         * drain unread data, state switch to reflect user close, and
                    263:         * send segment (e.g. FIN) to peer.  Socket will be really disconnected
                    264:         * when peer sends FIN and acks ours.
                    265:         *
                    266:         * SHOULD IMPLEMENT LATER PRU_CONNECT VIA REALLOC TCPCB.
                    267:         */
                    268:        case PRU_DISCONNECT:
                    269:                if ((tp = tcp_disconnect(tp)) == 0)
                    270:                        tuba_pcbdetach(isop);
                    271:                break;
                    272: 
                    273:        /*
                    274:         * Accept a connection.  Essentially all the work is
                    275:         * done at higher levels; just return the address
                    276:         * of the peer, storing through addr.
                    277:         */
                    278:        case PRU_ACCEPT:
                    279:                bcopy((caddr_t)isop->isop_faddr, mtod(nam, caddr_t),
                    280:                        nam->m_len = isop->isop_faddr->siso_len);
                    281:                break;
                    282: 
                    283:        /*
                    284:         * Mark the connection as being incapable of further output.
                    285:         */
                    286:        case PRU_SHUTDOWN:
                    287:                socantsendmore(so);
                    288:                tp = tcp_usrclosed(tp);
                    289:                if (tp)
                    290:                        error = tcp_output(tp);
                    291:                else
                    292:                        tuba_pcbdetach(isop);
                    293:                break;
                    294:        /*
                    295:         * Abort the TCP.
                    296:         */
                    297:        case PRU_ABORT:
                    298:                if ((tp = tcp_drop(tp, ECONNABORTED)) == 0)
                    299:                        tuba_pcbdetach(isop);
                    300:                break;
                    301: 
                    302: 
                    303:        case PRU_SOCKADDR:
                    304:                if (isop->isop_laddr)
                    305:                        bcopy((caddr_t)isop->isop_laddr, mtod(nam, caddr_t),
                    306:                                nam->m_len = isop->isop_laddr->siso_len);
                    307:                break;
                    308: 
                    309:        case PRU_PEERADDR:
                    310:                if (isop->isop_faddr)
                    311:                        bcopy((caddr_t)isop->isop_faddr, mtod(nam, caddr_t),
                    312:                                nam->m_len = isop->isop_faddr->siso_len);
                    313:                break;
                    314: 
                    315:        default:
                    316:                error = tcp_usrreq(so, req, m, nam, control);
                    317:                goto notrace;
                    318:        }
                    319:        if (tp && (so->so_options & SO_DEBUG))
                    320:                tcp_trace(TA_USER, ostate, tp, (struct tcpiphdr *)0, req);
                    321: notrace:
                    322:        splx(s);
                    323:        return(error);
                    324: }
                    325: 
                    326: tuba_ctloutput(op, so, level, optname, mp)
                    327:        int op;
                    328:        struct socket *so;
                    329:        int level, optname;
                    330:        struct mbuf **mp;
                    331: {
                    332:        int clnp_ctloutput(), tcp_ctloutput();
                    333: 
                    334:        return ((level != IPPROTO_TCP ? clnp_ctloutput : tcp_ctloutput)
                    335:                        (op, so, level, optname, mp));
                    336: }

unix.superglobalmegacorp.com

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