|
|
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.