Annotation of kernel/kern/mach_net_tcp.c, revision 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:  * Mach Operating System
        !            27:  * Copyright (c) 1989 Carnegie-Mellon University
        !            28:  * Copyright (c) 1988 Carnegie-Mellon University
        !            29:  * Copyright (c) 1987 Carnegie-Mellon University
        !            30:  * All rights reserved.  The CMU software License Agreement specifies
        !            31:  * the terms and conditions for use and redistribution.
        !            32:  */
        !            33: /*
        !            34:  * File:       mach_net_tcp.c
        !            35:  * Purpose:
        !            36:  *     Message interface to TCP. To be used primarily by the network server,
        !            37:  *     in cooperation with the kernel IPC code.
        !            38:  */
        !            39: 
        !            40: #import <sys/param.h>
        !            41: #import <sys/systm.h>
        !            42: #import <sys/mbuf.h>
        !            43: #import <sys/socket.h>
        !            44: #import <sys/socketvar.h>
        !            45: #import <sys/uio.h>
        !            46: #import <mach/kern_return.h>
        !            47: #import <mach/port.h>
        !            48: #import <kern/parallel.h>
        !            49: #import <sys/errno.h>
        !            50: #import <kern/xpr.h>
        !            51: 
        !            52: /*
        !            53:  * Global variable to hold the current error code (a.k.a. u.u_error).
        !            54:  */
        !            55: int    np_error;
        !            56: 
        !            57: kern_return_t
        !            58: mach_tcp_init(ServPort, tcp_port)
        !            59: port_t         ServPort;
        !            60: port_t         *tcp_port;
        !            61: {
        !            62:        /*
        !            63:         * Nothing yet ...
        !            64:         */
        !            65:        return KERN_SUCCESS;
        !            66: }
        !            67: 
        !            68: 
        !            69: kern_return_t
        !            70: mach_tcp_socket(ServPort, so)
        !            71:        port_t          ServPort;
        !            72:        struct socket   **so;
        !            73: {
        !            74:        unix_master();
        !            75:        np_error = socreate(AF_INET,so,SOCK_STREAM,0);
        !            76:        unix_release();
        !            77:        if (np_error)
        !            78:                return KERN_FAILURE;
        !            79:        else
        !            80:                return KERN_SUCCESS;
        !            81: }
        !            82: 
        !            83: 
        !            84: kern_return_t
        !            85: mach_tcp_close(ServPort, so)
        !            86:        port_t          ServPort;
        !            87:        struct socket   *so;
        !            88: {
        !            89:        unix_master();
        !            90:        np_error = soclose(so);
        !            91:        XPR(XPR_TCP,("mach_tcp_close: np_error=%d, so=0x%x",np_error,so));
        !            92:        unix_release();
        !            93:        if (np_error)
        !            94:                return KERN_FAILURE;
        !            95:        else
        !            96:                return KERN_SUCCESS;
        !            97: }
        !            98: 
        !            99: 
        !           100: kern_return_t
        !           101: mach_tcp_bind(ServPort, so, name, namelen)
        !           102:        port_t          ServPort;
        !           103:        struct socket   *so;
        !           104:        caddr_t         name;
        !           105:        int             namelen;
        !           106: {
        !           107:        struct mbuf     *m;
        !           108: 
        !           109:        unix_master();
        !           110:        m = m_get(M_WAIT, MT_SONAME);
        !           111:        m->m_next = NULL;
        !           112:        m->m_off = MMINOFF;
        !           113:        m->m_len = namelen;
        !           114:        bcopy(name,mtod(m,caddr_t),namelen);
        !           115:        np_error = sobind(so,m);
        !           116:        m_free(m);
        !           117:        so->so_options |= SO_CANTSIG;
        !           118:        unix_release();
        !           119:        if (np_error)
        !           120:                return KERN_FAILURE;
        !           121:        else
        !           122:                return KERN_SUCCESS;
        !           123: }
        !           124: 
        !           125: 
        !           126: kern_return_t
        !           127: mach_tcp_listen(ServPort, so, backlog)
        !           128:        port_t          ServPort;
        !           129:        struct socket   *so;
        !           130:        int             backlog;
        !           131: {
        !           132:        unix_master();
        !           133:        np_error = solisten(so,backlog);
        !           134:        unix_release();
        !           135:        if (np_error)
        !           136:                return KERN_FAILURE;
        !           137:        else
        !           138:                return KERN_SUCCESS;
        !           139: }
        !           140: 
        !           141: 
        !           142: kern_return_t
        !           143: mach_tcp_accept(ServPort, so, name, namelen, newso)
        !           144:        port_t          ServPort;
        !           145:        struct socket   *so;
        !           146:        caddr_t         name;
        !           147:        int             *namelen;
        !           148:        struct socket   **newso;
        !           149: {
        !           150:        struct mbuf     *nam;
        !           151:        int             s;
        !           152: 
        !           153:        unix_master();
        !           154:        s = splnet();
        !           155:        XPR(XPR_TCP,("mach_tcp_accept entered, so=0x%x, newso=0x%x",so,newso));
        !           156:        if ((so->so_options & SO_ACCEPTCONN) == 0) {
        !           157:                np_error = EINVAL;
        !           158:                XPR(XPR_TCP,("mach_tcp_accept failed, no SO_ACCEPTCONN, so=0x%x",so));
        !           159:                splx(s);
        !           160:                unix_release();
        !           161:                return KERN_FAILURE;
        !           162:        }
        !           163:        if ((so->so_state & SS_NBIO) && so->so_qlen == 0) {
        !           164:                np_error = EWOULDBLOCK;
        !           165:                XPR(XPR_TCP,("mach_tcp_accept failed, EWOULDBLOCK, so=0x%x",so));
        !           166:                splx(s);
        !           167:                unix_release();
        !           168:                return KERN_FAILURE;
        !           169:        }
        !           170:        while (so->so_qlen == 0 && so->so_error == 0) {
        !           171:                XPR(XPR_TCP,("mach_tcp_accept top of sleep loop, so=0x%x",so));
        !           172:                if (so->so_state & SS_CANTRCVMORE) {
        !           173:                        XPR(XPR_TCP,("mach_tcp_accept SS_CANTRCVMORE in sleep loop, so=0x%x",so));
        !           174:                        so->so_error = ECONNABORTED;
        !           175:                        break;
        !           176:                }
        !           177:                sleep((caddr_t)&so->so_timeo, PZERO+1);
        !           178:        }
        !           179:        XPR(XPR_TCP,("mach_tcp_accept out of sleep loop, so=0x%x",so));
        !           180:        if (so->so_error) {
        !           181:                np_error = so->so_error;
        !           182:                so->so_error = 0;
        !           183:                XPR(XPR_TCP,("mach_tcp_accept so_error=%d, so=0x%x",np_error,so));
        !           184:                splx(s);
        !           185:                unix_release();
        !           186:                return KERN_FAILURE;
        !           187:        }
        !           188:        { struct socket *aso = so->so_q;
        !           189:          if (soqremque(aso, 1) == 0)
        !           190:                panic("accept");
        !           191:          *newso = aso;
        !           192:        }
        !           193:        nam = m_get(M_WAIT, MT_SONAME);
        !           194:        (void) soaccept(*newso, nam);
        !           195:        XPR(XPR_TCP,("mach_tcp_accept out of soaccept, np_error=%d, so=0x%x, *newso=0x%x",np_error,so,*newso));
        !           196:        if (name) {
        !           197:                if (*namelen > nam->m_len)
        !           198:                        *namelen = nam->m_len;
        !           199:                /* SHOULD COPY OUT A CHAIN HERE */
        !           200:                bcopy(mtod(nam, caddr_t), name, *namelen);
        !           201:        }
        !           202:        m_freem(nam);
        !           203:        splx(s);
        !           204:        unix_release();
        !           205:        if (np_error)
        !           206:                return KERN_FAILURE;
        !           207:        else
        !           208:                return KERN_SUCCESS;
        !           209: }
        !           210: 
        !           211: 
        !           212: kern_return_t
        !           213: mach_tcp_connect(ServPort, so, name, namelen)
        !           214:        port_t          ServPort;
        !           215:        struct socket   *so;
        !           216:        caddr_t         name;
        !           217:        int             namelen;
        !           218: {
        !           219:        struct mbuf     *nam;
        !           220:        int             s;
        !           221: 
        !           222:        unix_master();
        !           223:        if ((so->so_state & SS_NBIO) &&
        !           224:            (so->so_state & SS_ISCONNECTING)) {
        !           225:                np_error = EALREADY;
        !           226:                XPR(XPR_TCP,("mach_tcp_connect: already connecting, so=0x%x",so));
        !           227:                unix_release();
        !           228:                return KERN_FAILURE;
        !           229:        }
        !           230:        nam = m_get(M_WAIT, MT_SONAME);
        !           231:        if (nam == NULL) {
        !           232:                np_error = ENOBUFS;             
        !           233:                XPR(XPR_TCP,("mach_tcp_connect: no buffers, so=0x%x",so));
        !           234:                unix_release();
        !           235:                return KERN_FAILURE;
        !           236:        }
        !           237:        nam->m_len = namelen;
        !           238:        bcopy(name,mtod(nam,caddr_t),namelen);
        !           239:        np_error = soconnect(so, nam);
        !           240:        XPR(XPR_TCP,("mach_tcp_connect: back from soconnect, np_error=%d, so=0x%x",np_error,so));
        !           241:        if (np_error)
        !           242:                goto bad;
        !           243:        if ((so->so_state & SS_NBIO) &&
        !           244:            (so->so_state & SS_ISCONNECTING)) {
        !           245:                np_error = EINPROGRESS;
        !           246:                XPR(XPR_TCP,("mach_tcp_connect: in progress, so=0x%x",so));
        !           247:                m_freem(nam);
        !           248:                unix_release();
        !           249:                return KERN_FAILURE;
        !           250:        }
        !           251:        s = splnet();
        !           252: /*
        !           253:        if (setjmp(&u.u_qsave)) {
        !           254:                if (u.u_error == 0)
        !           255:                        u.u_error = EINTR;
        !           256:                goto bad2;
        !           257:        }
        !           258: */
        !           259:        while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0)
        !           260:                sleep((caddr_t)&so->so_timeo, PZERO+1);
        !           261:        np_error = so->so_error;
        !           262:        so->so_error = 0;
        !           263: /* bad2: */
        !           264:        splx(s);
        !           265:        XPR(XPR_TCP,("mach_tcp_connect: woke up, np_error=%d, so=0x%x",np_error,so));
        !           266: bad:
        !           267:        so->so_state &= ~SS_ISCONNECTING;
        !           268:        m_freem(nam);
        !           269:        unix_release();
        !           270:        if (np_error)
        !           271:                return KERN_FAILURE;
        !           272:        else
        !           273:                return KERN_SUCCESS;
        !           274: }
        !           275: 
        !           276: 
        !           277: 
        !           278: kern_return_t
        !           279: mach_tcp_send(ServPort, so, buf, len, flags)
        !           280:        port_t          ServPort;
        !           281:        struct socket   *so;
        !           282:        caddr_t         buf;
        !           283:        int             *len;
        !           284:        int             flags;
        !           285:        /*
        !           286:         * Note: len is an in/out argument, returning the number
        !           287:         * of bytes actually sent.
        !           288:         */
        !           289: {
        !           290:        int             error;
        !           291:        struct iovec    aiov;
        !           292:        struct uio      auio;
        !           293: 
        !           294:        unix_master();
        !           295:        aiov.iov_base = buf;
        !           296:        aiov.iov_len = *len;
        !           297:        auio.uio_iov = &aiov;
        !           298:        auio.uio_iovcnt = 1;
        !           299:        auio.uio_segflg = UIO_SYSSPACE;
        !           300:        auio.uio_offset = 0;                    /* XXX */
        !           301:        auio.uio_resid = *len;
        !           302:        error = sosend(so, 0, &auio, flags, 0);
        !           303:        *len = *len - auio.uio_resid;
        !           304:        unix_release();
        !           305:        if (error)
        !           306:                return KERN_FAILURE;
        !           307:        else
        !           308:                return KERN_SUCCESS;
        !           309: }
        !           310: 
        !           311: 
        !           312: kern_return_t
        !           313: mach_tcp_recv(ServPort, so, buf, len, flags)
        !           314:        port_t          ServPort;
        !           315:        struct socket   *so;
        !           316:        caddr_t         buf;
        !           317:        int             *len;
        !           318:        int             flags;
        !           319:        /*
        !           320:         * Note: len is an in/out argument, returning the number
        !           321:         * of bytes actually received.
        !           322:         */
        !           323: {
        !           324:        int             error;
        !           325:        struct iovec    aiov;
        !           326:        struct uio      auio;
        !           327:        struct mbuf     *from, *rights;
        !           328: 
        !           329:        unix_master();
        !           330:        aiov.iov_base = buf;
        !           331:        aiov.iov_len = *len;
        !           332:        auio.uio_iov = &aiov;
        !           333:        auio.uio_iovcnt = 1;
        !           334:        auio.uio_segflg = UIO_SYSSPACE;
        !           335:        auio.uio_offset = 0;                    /* XXX */
        !           336:        auio.uio_resid = *len;
        !           337:        error = soreceive(so, &from, &auio, flags, &rights);
        !           338:        *len = *len - auio.uio_resid;
        !           339:        if (rights)
        !           340:                m_freem(rights);
        !           341:        if (from)
        !           342:                m_freem(from);
        !           343:        unix_release();
        !           344:        if (error)
        !           345:                return KERN_FAILURE;
        !           346:        else
        !           347:                return KERN_SUCCESS;
        !           348: }
        !           349: 
        !           350: 
        !           351: 
        !           352: 

unix.superglobalmegacorp.com

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