Deleted Added
full compact
uipc_socket.c (15701) uipc_socket.c (17096)
1/*
2 * Copyright (c) 1982, 1986, 1988, 1990, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 17 unchanged lines hidden (view full) ---

26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * @(#)uipc_socket.c 8.3 (Berkeley) 4/15/94
1/*
2 * Copyright (c) 1982, 1986, 1988, 1990, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 17 unchanged lines hidden (view full) ---

26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * @(#)uipc_socket.c 8.3 (Berkeley) 4/15/94
34 * $Id: uipc_socket.c,v 1.17 1996/04/16 03:50:08 davidg Exp $
34 * $Id: uipc_socket.c,v 1.18 1996/05/09 20:14:57 wollman Exp $
35 */
36
37#include <sys/param.h>
38#include <sys/queue.h>
39#include <sys/systm.h>
40#include <sys/proc.h>
41#include <sys/file.h>
42#include <sys/malloc.h>

--- 29 unchanged lines hidden (view full) ---

72 register struct protosw *prp;
73 register struct socket *so;
74 register int error;
75
76 if (proto)
77 prp = pffindproto(dom, proto, type);
78 else
79 prp = pffindtype(dom, type);
35 */
36
37#include <sys/param.h>
38#include <sys/queue.h>
39#include <sys/systm.h>
40#include <sys/proc.h>
41#include <sys/file.h>
42#include <sys/malloc.h>

--- 29 unchanged lines hidden (view full) ---

72 register struct protosw *prp;
73 register struct socket *so;
74 register int error;
75
76 if (proto)
77 prp = pffindproto(dom, proto, type);
78 else
79 prp = pffindtype(dom, type);
80 if (prp == 0 || prp->pr_usrreq == 0)
80 if (prp == 0 || prp->pr_usrreqs == 0)
81 return (EPROTONOSUPPORT);
82 if (prp->pr_type != type)
83 return (EPROTOTYPE);
84 MALLOC(so, struct socket *, sizeof(*so), M_SOCKET, M_WAIT);
85 bzero((caddr_t)so, sizeof(*so));
86 TAILQ_INIT(&so->so_incomp);
87 TAILQ_INIT(&so->so_comp);
88 so->so_type = type;
89 if (p->p_ucred->cr_uid == 0)
90 so->so_state = SS_PRIV;
91 so->so_proto = prp;
81 return (EPROTONOSUPPORT);
82 if (prp->pr_type != type)
83 return (EPROTOTYPE);
84 MALLOC(so, struct socket *, sizeof(*so), M_SOCKET, M_WAIT);
85 bzero((caddr_t)so, sizeof(*so));
86 TAILQ_INIT(&so->so_incomp);
87 TAILQ_INIT(&so->so_comp);
88 so->so_type = type;
89 if (p->p_ucred->cr_uid == 0)
90 so->so_state = SS_PRIV;
91 so->so_proto = prp;
92 error =
93 (*prp->pr_usrreq)(so, PRU_ATTACH,
94 (struct mbuf *)0, (struct mbuf *)proto, (struct mbuf *)0);
92 error = (*prp->pr_usrreqs->pru_attach)(so, proto);
95 if (error) {
96 so->so_state |= SS_NOFDREF;
97 sofree(so);
98 return (error);
99 }
100 *aso = so;
101 return (0);
102}
103
104int
105sobind(so, nam)
106 struct socket *so;
107 struct mbuf *nam;
108{
109 int s = splnet();
110 int error;
111
93 if (error) {
94 so->so_state |= SS_NOFDREF;
95 sofree(so);
96 return (error);
97 }
98 *aso = so;
99 return (0);
100}
101
102int
103sobind(so, nam)
104 struct socket *so;
105 struct mbuf *nam;
106{
107 int s = splnet();
108 int error;
109
112 error =
113 (*so->so_proto->pr_usrreq)(so, PRU_BIND,
114 (struct mbuf *)0, nam, (struct mbuf *)0);
110 error = (*so->so_proto->pr_usrreqs->pru_bind)(so, nam);
115 splx(s);
116 return (error);
117}
118
119int
120solisten(so, backlog)
121 register struct socket *so;
122 int backlog;
123{
124 int s = splnet(), error;
125
111 splx(s);
112 return (error);
113}
114
115int
116solisten(so, backlog)
117 register struct socket *so;
118 int backlog;
119{
120 int s = splnet(), error;
121
126 error =
127 (*so->so_proto->pr_usrreq)(so, PRU_LISTEN,
128 (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0);
122 error = (*so->so_proto->pr_usrreqs->pru_listen)(so);
129 if (error) {
130 splx(s);
131 return (error);
132 }
133 if (so->so_comp.tqh_first == NULL)
134 so->so_options |= SO_ACCEPTCONN;
135 if (backlog < 0 || backlog > somaxconn)
136 backlog = somaxconn;

--- 68 unchanged lines hidden (view full) ---

205 PSOCK | PCATCH, "soclos", so->so_linger);
206 if (error)
207 break;
208 }
209 }
210 }
211drop:
212 if (so->so_pcb) {
123 if (error) {
124 splx(s);
125 return (error);
126 }
127 if (so->so_comp.tqh_first == NULL)
128 so->so_options |= SO_ACCEPTCONN;
129 if (backlog < 0 || backlog > somaxconn)
130 backlog = somaxconn;

--- 68 unchanged lines hidden (view full) ---

199 PSOCK | PCATCH, "soclos", so->so_linger);
200 if (error)
201 break;
202 }
203 }
204 }
205drop:
206 if (so->so_pcb) {
213 int error2 =
214 (*so->so_proto->pr_usrreq)(so, PRU_DETACH,
215 (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0);
207 int error2 = (*so->so_proto->pr_usrreqs->pru_detach)(so);
216 if (error == 0)
217 error = error2;
218 }
219discard:
220 if (so->so_state & SS_NOFDREF)
221 panic("soclose: NOFDREF");
222 so->so_state |= SS_NOFDREF;
223 sofree(so);

--- 4 unchanged lines hidden (view full) ---

228/*
229 * Must be called at splnet...
230 */
231int
232soabort(so)
233 struct socket *so;
234{
235
208 if (error == 0)
209 error = error2;
210 }
211discard:
212 if (so->so_state & SS_NOFDREF)
213 panic("soclose: NOFDREF");
214 so->so_state |= SS_NOFDREF;
215 sofree(so);

--- 4 unchanged lines hidden (view full) ---

220/*
221 * Must be called at splnet...
222 */
223int
224soabort(so)
225 struct socket *so;
226{
227
236 return (
237 (*so->so_proto->pr_usrreq)(so, PRU_ABORT,
238 (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0));
228 return (*so->so_proto->pr_usrreqs->pru_abort)(so);
239}
240
241int
242soaccept(so, nam)
243 register struct socket *so;
244 struct mbuf *nam;
245{
246 int s = splnet();
247 int error;
248
249 if ((so->so_state & SS_NOFDREF) == 0)
250 panic("soaccept: !NOFDREF");
251 so->so_state &= ~SS_NOFDREF;
229}
230
231int
232soaccept(so, nam)
233 register struct socket *so;
234 struct mbuf *nam;
235{
236 int s = splnet();
237 int error;
238
239 if ((so->so_state & SS_NOFDREF) == 0)
240 panic("soaccept: !NOFDREF");
241 so->so_state &= ~SS_NOFDREF;
252 error = (*so->so_proto->pr_usrreq)(so, PRU_ACCEPT,
253 (struct mbuf *)0, nam, (struct mbuf *)0);
242 error = (*so->so_proto->pr_usrreqs->pru_accept)(so, nam);
254 splx(s);
255 return (error);
256}
257
258int
259soconnect(so, nam)
260 register struct socket *so;
261 struct mbuf *nam;

--- 10 unchanged lines hidden (view full) ---

272 * This allows user to disconnect by connecting to, e.g.,
273 * a null address.
274 */
275 if (so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING) &&
276 ((so->so_proto->pr_flags & PR_CONNREQUIRED) ||
277 (error = sodisconnect(so))))
278 error = EISCONN;
279 else
243 splx(s);
244 return (error);
245}
246
247int
248soconnect(so, nam)
249 register struct socket *so;
250 struct mbuf *nam;

--- 10 unchanged lines hidden (view full) ---

261 * This allows user to disconnect by connecting to, e.g.,
262 * a null address.
263 */
264 if (so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING) &&
265 ((so->so_proto->pr_flags & PR_CONNREQUIRED) ||
266 (error = sodisconnect(so))))
267 error = EISCONN;
268 else
280 error = (*so->so_proto->pr_usrreq)(so, PRU_CONNECT,
281 (struct mbuf *)0, nam, (struct mbuf *)0);
269 error = (*so->so_proto->pr_usrreqs->pru_connect)(so, nam);
282 splx(s);
283 return (error);
284}
285
286int
287soconnect2(so1, so2)
288 register struct socket *so1;
289 struct socket *so2;
290{
291 int s = splnet();
292 int error;
293
270 splx(s);
271 return (error);
272}
273
274int
275soconnect2(so1, so2)
276 register struct socket *so1;
277 struct socket *so2;
278{
279 int s = splnet();
280 int error;
281
294 error = (*so1->so_proto->pr_usrreq)(so1, PRU_CONNECT2,
295 (struct mbuf *)0, (struct mbuf *)so2, (struct mbuf *)0);
282 error = (*so1->so_proto->pr_usrreqs->pru_connect2)(so1, so2);
296 splx(s);
297 return (error);
298}
299
300int
301sodisconnect(so)
302 register struct socket *so;
303{
304 int s = splnet();
305 int error;
306
307 if ((so->so_state & SS_ISCONNECTED) == 0) {
308 error = ENOTCONN;
309 goto bad;
310 }
311 if (so->so_state & SS_ISDISCONNECTING) {
312 error = EALREADY;
313 goto bad;
314 }
283 splx(s);
284 return (error);
285}
286
287int
288sodisconnect(so)
289 register struct socket *so;
290{
291 int s = splnet();
292 int error;
293
294 if ((so->so_state & SS_ISCONNECTED) == 0) {
295 error = ENOTCONN;
296 goto bad;
297 }
298 if (so->so_state & SS_ISDISCONNECTING) {
299 error = EALREADY;
300 goto bad;
301 }
315 error = (*so->so_proto->pr_usrreq)(so, PRU_DISCONNECT,
316 (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0);
302 error = (*so->so_proto->pr_usrreqs->pru_disconnect)(so);
317bad:
318 splx(s);
319 return (error);
320}
321
322#define SBLOCKWAIT(f) (((f) & MSG_DONTWAIT) ? M_NOWAIT : M_WAITOK)
323/*
324 * Send on a socket.

--- 142 unchanged lines hidden (view full) ---

467 if (flags & MSG_EOR)
468 top->m_flags |= M_EOR;
469 break;
470 }
471 } while (space > 0 && atomic);
472 if (dontroute)
473 so->so_options |= SO_DONTROUTE;
474 s = splnet(); /* XXX */
303bad:
304 splx(s);
305 return (error);
306}
307
308#define SBLOCKWAIT(f) (((f) & MSG_DONTWAIT) ? M_NOWAIT : M_WAITOK)
309/*
310 * Send on a socket.

--- 142 unchanged lines hidden (view full) ---

453 if (flags & MSG_EOR)
454 top->m_flags |= M_EOR;
455 break;
456 }
457 } while (space > 0 && atomic);
458 if (dontroute)
459 so->so_options |= SO_DONTROUTE;
460 s = splnet(); /* XXX */
475 error = (*so->so_proto->pr_usrreq)(so,
476 (flags & MSG_OOB) ? PRU_SENDOOB :
461 error = (*so->so_proto->pr_usrreqs->pru_send)(so,
462 (flags & MSG_OOB) ? PRUS_OOB :
477 /*
478 * If the user set MSG_EOF, the protocol
479 * understands this flag and nothing left to
480 * send then use PRU_SEND_EOF instead of PRU_SEND.
481 */
482 ((flags & MSG_EOF) &&
483 (so->so_proto->pr_flags & PR_IMPLOPCL) &&
484 (resid <= 0)) ?
463 /*
464 * If the user set MSG_EOF, the protocol
465 * understands this flag and nothing left to
466 * send then use PRU_SEND_EOF instead of PRU_SEND.
467 */
468 ((flags & MSG_EOF) &&
469 (so->so_proto->pr_flags & PR_IMPLOPCL) &&
470 (resid <= 0)) ?
485 PRU_SEND_EOF : PRU_SEND,
471 PRUS_EOF : 0,
486 top, addr, control);
487 splx(s);
488 if (dontroute)
489 so->so_options &= ~SO_DONTROUTE;
490 clen = 0;
491 control = 0;
492 top = 0;
493 mp = &top;

--- 50 unchanged lines hidden (view full) ---

544 if (controlp)
545 *controlp = 0;
546 if (flagsp)
547 flags = *flagsp &~ MSG_EOR;
548 else
549 flags = 0;
550 if (flags & MSG_OOB) {
551 m = m_get(M_WAIT, MT_DATA);
472 top, addr, control);
473 splx(s);
474 if (dontroute)
475 so->so_options &= ~SO_DONTROUTE;
476 clen = 0;
477 control = 0;
478 top = 0;
479 mp = &top;

--- 50 unchanged lines hidden (view full) ---

530 if (controlp)
531 *controlp = 0;
532 if (flagsp)
533 flags = *flagsp &~ MSG_EOR;
534 else
535 flags = 0;
536 if (flags & MSG_OOB) {
537 m = m_get(M_WAIT, MT_DATA);
552 error = (*pr->pr_usrreq)(so, PRU_RCVOOB,
553 m, (struct mbuf *)(flags & MSG_PEEK), (struct mbuf *)0);
538 error = (*pr->pr_usrreqs->pru_rcvoob)(so, m, flags & MSG_PEEK);
554 if (error)
555 goto bad;
556 do {
557 error = uiomove(mtod(m, caddr_t),
558 (int) min(uio->uio_resid, m->m_len), uio);
559 m = m_free(m);
560 } while (uio->uio_resid && error == 0 && m);
561bad:
562 if (m)
563 m_freem(m);
564 return (error);
565 }
566 if (mp)
567 *mp = (struct mbuf *)0;
568 if (so->so_state & SS_ISCONFIRMING && uio->uio_resid)
539 if (error)
540 goto bad;
541 do {
542 error = uiomove(mtod(m, caddr_t),
543 (int) min(uio->uio_resid, m->m_len), uio);
544 m = m_free(m);
545 } while (uio->uio_resid && error == 0 && m);
546bad:
547 if (m)
548 m_freem(m);
549 return (error);
550 }
551 if (mp)
552 *mp = (struct mbuf *)0;
553 if (so->so_state & SS_ISCONFIRMING && uio->uio_resid)
569 (*pr->pr_usrreq)(so, PRU_RCVD, (struct mbuf *)0,
570 (struct mbuf *)0, (struct mbuf *)0);
554 (*pr->pr_usrreqs->pru_rcvd)(so, 0);
571
572restart:
573 error = sblock(&so->so_rcv, SBLOCKWAIT(flags));
574 if (error)
575 return (error);
576 s = splnet();
577
578 m = so->so_rcv.sb_mb;

--- 220 unchanged lines hidden (view full) ---

799 flags |= MSG_TRUNC;
800 if ((flags & MSG_PEEK) == 0)
801 (void) sbdroprecord(&so->so_rcv);
802 }
803 if ((flags & MSG_PEEK) == 0) {
804 if (m == 0)
805 so->so_rcv.sb_mb = nextrecord;
806 if (pr->pr_flags & PR_WANTRCVD && so->so_pcb)
555
556restart:
557 error = sblock(&so->so_rcv, SBLOCKWAIT(flags));
558 if (error)
559 return (error);
560 s = splnet();
561
562 m = so->so_rcv.sb_mb;

--- 220 unchanged lines hidden (view full) ---

783 flags |= MSG_TRUNC;
784 if ((flags & MSG_PEEK) == 0)
785 (void) sbdroprecord(&so->so_rcv);
786 }
787 if ((flags & MSG_PEEK) == 0) {
788 if (m == 0)
789 so->so_rcv.sb_mb = nextrecord;
790 if (pr->pr_flags & PR_WANTRCVD && so->so_pcb)
807 (*pr->pr_usrreq)(so, PRU_RCVD, (struct mbuf *)0,
808 (struct mbuf *)flags, (struct mbuf *)0);
791 (*pr->pr_usrreqs->pru_rcvd)(so, flags);
809 }
810 if (orig_resid == uio->uio_resid && orig_resid &&
811 (flags & MSG_EOR) == 0 && (so->so_state & SS_CANTRCVMORE) == 0) {
812 sbunlock(&so->so_rcv);
813 splx(s);
814 goto restart;
815 }
816

--- 11 unchanged lines hidden (view full) ---

828 register int how;
829{
830 register struct protosw *pr = so->so_proto;
831
832 how++;
833 if (how & FREAD)
834 sorflush(so);
835 if (how & FWRITE)
792 }
793 if (orig_resid == uio->uio_resid && orig_resid &&
794 (flags & MSG_EOR) == 0 && (so->so_state & SS_CANTRCVMORE) == 0) {
795 sbunlock(&so->so_rcv);
796 splx(s);
797 goto restart;
798 }
799

--- 11 unchanged lines hidden (view full) ---

811 register int how;
812{
813 register struct protosw *pr = so->so_proto;
814
815 how++;
816 if (how & FREAD)
817 sorflush(so);
818 if (how & FWRITE)
836 return ((*pr->pr_usrreq)(so, PRU_SHUTDOWN,
837 (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0));
819 return ((*pr->pr_usrreqs->pru_shutdown)(so));
838 return (0);
839}
840
841void
842sorflush(so)
843 register struct socket *so;
844{
845 register struct sockbuf *sb = &so->so_rcv;

--- 242 unchanged lines hidden ---
820 return (0);
821}
822
823void
824sorflush(so)
825 register struct socket *so;
826{
827 register struct sockbuf *sb = &so->so_rcv;

--- 242 unchanged lines hidden ---