|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.