Print this page
XXXX adding PID information to netstat output
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/inet/sockmods/socksctp.c
+++ new/usr/src/uts/common/inet/sockmods/socksctp.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
↓ open down ↓ |
22 lines elided |
↑ open up ↑ |
23 23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24 24 */
25 25
26 26 #include <sys/types.h>
27 27 #include <sys/t_lock.h>
28 28 #include <sys/param.h>
29 29 #include <sys/systm.h>
30 30 #include <sys/buf.h>
31 31 #include <sys/vfs.h>
32 32 #include <sys/vnode.h>
33 +#include <sys/fcntl.h>
33 34 #include <sys/debug.h>
34 35 #include <sys/errno.h>
35 36 #include <sys/stropts.h>
36 37 #include <sys/cmn_err.h>
37 38 #include <sys/sysmacros.h>
38 39 #include <sys/filio.h>
39 40 #include <sys/policy.h>
40 41
41 42 #include <sys/project.h>
42 43 #include <sys/tihdr.h>
43 44 #include <sys/strsubr.h>
44 45 #include <sys/esunddi.h>
45 46 #include <sys/ddi.h>
46 47
47 48 #include <sys/sockio.h>
48 49 #include <sys/socket.h>
49 50 #include <sys/socketvar.h>
50 51 #include <sys/strsun.h>
51 52
52 53 #include <netinet/sctp.h>
53 54 #include <inet/sctp_itf.h>
54 55 #include <fs/sockfs/sockcommon.h>
55 56 #include "socksctp.h"
56 57
57 58 /*
58 59 * SCTP sockfs sonode operations, 1-1 socket
59 60 */
60 61 static int sosctp_init(struct sonode *, struct sonode *, struct cred *, int);
61 62 static int sosctp_accept(struct sonode *, int, struct cred *, struct sonode **);
62 63 static int sosctp_bind(struct sonode *, struct sockaddr *, socklen_t, int,
63 64 struct cred *);
64 65 static int sosctp_listen(struct sonode *, int, struct cred *);
65 66 static int sosctp_connect(struct sonode *, struct sockaddr *, socklen_t,
66 67 int, int, struct cred *);
67 68 static int sosctp_recvmsg(struct sonode *, struct nmsghdr *, struct uio *,
68 69 struct cred *);
69 70 static int sosctp_sendmsg(struct sonode *, struct nmsghdr *, struct uio *,
70 71 struct cred *);
71 72 static int sosctp_getpeername(struct sonode *, struct sockaddr *, socklen_t *,
72 73 boolean_t, struct cred *);
73 74 static int sosctp_getsockname(struct sonode *, struct sockaddr *, socklen_t *,
74 75 struct cred *);
75 76 static int sosctp_shutdown(struct sonode *, int, struct cred *);
76 77 static int sosctp_getsockopt(struct sonode *, int, int, void *, socklen_t *,
77 78 int, struct cred *);
78 79 static int sosctp_setsockopt(struct sonode *, int, int, const void *,
79 80 socklen_t, struct cred *);
80 81 static int sosctp_ioctl(struct sonode *, int, intptr_t, int, struct cred *,
81 82 int32_t *);
82 83 static int sosctp_close(struct sonode *, int, struct cred *);
83 84 void sosctp_fini(struct sonode *, struct cred *);
84 85
85 86 /*
86 87 * SCTP sockfs sonode operations, 1-N socket
87 88 */
88 89 static int sosctp_seq_connect(struct sonode *, struct sockaddr *,
89 90 socklen_t, int, int, struct cred *);
90 91 static int sosctp_seq_sendmsg(struct sonode *, struct nmsghdr *, struct uio *,
91 92 struct cred *);
92 93
93 94 /*
94 95 * Socket association upcalls, 1-N socket connection
95 96 */
96 97 sock_upper_handle_t sctp_assoc_newconn(sock_upper_handle_t,
97 98 sock_lower_handle_t, sock_downcalls_t *, struct cred *, pid_t,
98 99 sock_upcalls_t **);
↓ open down ↓ |
56 lines elided |
↑ open up ↑ |
99 100 static void sctp_assoc_connected(sock_upper_handle_t, sock_connid_t,
100 101 struct cred *, pid_t);
101 102 static int sctp_assoc_disconnected(sock_upper_handle_t, sock_connid_t, int);
102 103 static void sctp_assoc_disconnecting(sock_upper_handle_t, sock_opctl_action_t,
103 104 uintptr_t arg);
104 105 static ssize_t sctp_assoc_recv(sock_upper_handle_t, mblk_t *, size_t, int,
105 106 int *, boolean_t *);
106 107 static void sctp_assoc_xmitted(sock_upper_handle_t, boolean_t);
107 108 static void sctp_assoc_properties(sock_upper_handle_t,
108 109 struct sock_proto_props *);
110 +static conn_pid_node_list_hdr_t *
111 + sctp_get_sock_pid_list(sock_upper_handle_t);
109 112
110 113 sonodeops_t sosctp_sonodeops = {
111 114 sosctp_init, /* sop_init */
112 115 sosctp_accept, /* sop_accept */
113 116 sosctp_bind, /* sop_bind */
114 117 sosctp_listen, /* sop_listen */
115 118 sosctp_connect, /* sop_connect */
116 119 sosctp_recvmsg, /* sop_recvmsg */
117 120 sosctp_sendmsg, /* sop_sendmsg */
118 121 so_sendmblk_notsupp, /* sop_sendmblk */
119 122 sosctp_getpeername, /* sop_getpeername */
120 123 sosctp_getsockname, /* sop_getsockname */
121 124 sosctp_shutdown, /* sop_shutdown */
122 125 sosctp_getsockopt, /* sop_getsockopt */
123 126 sosctp_setsockopt, /* sop_setsockopt */
124 127 sosctp_ioctl, /* sop_ioctl */
125 128 so_poll, /* sop_poll */
126 129 sosctp_close, /* sop_close */
127 130 };
128 131
129 132 sonodeops_t sosctp_seq_sonodeops = {
130 133 sosctp_init, /* sop_init */
131 134 so_accept_notsupp, /* sop_accept */
132 135 sosctp_bind, /* sop_bind */
133 136 sosctp_listen, /* sop_listen */
134 137 sosctp_seq_connect, /* sop_connect */
135 138 sosctp_recvmsg, /* sop_recvmsg */
136 139 sosctp_seq_sendmsg, /* sop_sendmsg */
137 140 so_sendmblk_notsupp, /* sop_sendmblk */
138 141 so_getpeername_notsupp, /* sop_getpeername */
139 142 sosctp_getsockname, /* sop_getsockname */
140 143 so_shutdown_notsupp, /* sop_shutdown */
141 144 sosctp_getsockopt, /* sop_getsockopt */
142 145 sosctp_setsockopt, /* sop_setsockopt */
143 146 sosctp_ioctl, /* sop_ioctl */
144 147 so_poll, /* sop_poll */
145 148 sosctp_close, /* sop_close */
146 149 };
147 150
148 151 /* All the upcalls expect the upper handle to be sonode. */
149 152 sock_upcalls_t sosctp_sock_upcalls = {
150 153 so_newconn,
151 154 so_connected,
152 155 so_disconnected,
153 156 so_opctl,
154 157 so_queue_msg,
155 158 so_set_prop,
156 159 so_txq_full,
157 160 NULL, /* su_signal_oob */
158 161 };
159 162
160 163 /* All the upcalls expect the upper handle to be sctp_sonode/sctp_soassoc. */
↓ open down ↓ |
42 lines elided |
↑ open up ↑ |
161 164 sock_upcalls_t sosctp_assoc_upcalls = {
162 165 sctp_assoc_newconn,
163 166 sctp_assoc_connected,
164 167 sctp_assoc_disconnected,
165 168 sctp_assoc_disconnecting,
166 169 sctp_assoc_recv,
167 170 sctp_assoc_properties,
168 171 sctp_assoc_xmitted,
169 172 NULL, /* su_recv_space */
170 173 NULL, /* su_signal_oob */
174 + NULL, /* su_set_error */
175 + NULL, /* su_closed */
176 + sctp_get_sock_pid_list
171 177 };
172 178
173 179 /* ARGSUSED */
174 180 static int
175 181 sosctp_init(struct sonode *so, struct sonode *pso, struct cred *cr, int flags)
176 182 {
177 183 struct sctp_sonode *ss;
178 184 struct sctp_sonode *pss;
179 185 sctp_sockbuf_limits_t sbl;
180 186 int err;
181 187
182 188 ss = SOTOSSO(so);
183 189
184 190 if (pso != NULL) {
185 191 /*
186 192 * Passive open, just inherit settings from parent. We should
187 193 * not end up here for SOCK_SEQPACKET type sockets, since no
188 194 * new sonode is created in that case.
189 195 */
190 196 ASSERT(so->so_type == SOCK_STREAM);
191 197 pss = SOTOSSO(pso);
192 198
193 199 mutex_enter(&pso->so_lock);
194 200 so->so_state |= (SS_ISBOUND | SS_ISCONNECTED |
195 201 (pso->so_state & SS_ASYNC));
196 202 sosctp_so_inherit(pss, ss);
197 203 so->so_proto_props = pso->so_proto_props;
198 204 so->so_mode = pso->so_mode;
199 205 mutex_exit(&pso->so_lock);
200 206
201 207 return (0);
202 208 }
203 209
204 210 if ((err = secpolicy_basic_net_access(cr)) != 0)
205 211 return (err);
206 212
207 213 if (so->so_type == SOCK_STREAM) {
208 214 so->so_proto_handle = (sock_lower_handle_t)sctp_create(so,
209 215 NULL, so->so_family, so->so_type, SCTP_CAN_BLOCK,
210 216 &sosctp_sock_upcalls, &sbl, cr);
211 217 so->so_mode = SM_CONNREQUIRED;
212 218 } else {
213 219 ASSERT(so->so_type == SOCK_SEQPACKET);
214 220 so->so_proto_handle = (sock_lower_handle_t)sctp_create(ss,
215 221 NULL, so->so_family, so->so_type, SCTP_CAN_BLOCK,
216 222 &sosctp_assoc_upcalls, &sbl, cr);
217 223 }
218 224
219 225 if (so->so_proto_handle == NULL)
220 226 return (ENOMEM);
221 227
222 228 so->so_rcvbuf = sbl.sbl_rxbuf;
223 229 so->so_rcvlowat = sbl.sbl_rxlowat;
224 230 so->so_sndbuf = sbl.sbl_txbuf;
225 231 so->so_sndlowat = sbl.sbl_txlowat;
226 232
227 233 return (0);
228 234 }
229 235
230 236 /*
231 237 * Accept incoming connection.
232 238 */
233 239 /*ARGSUSED*/
234 240 static int
235 241 sosctp_accept(struct sonode *so, int fflag, struct cred *cr,
236 242 struct sonode **nsop)
237 243 {
238 244 int error = 0;
239 245
240 246 if ((so->so_state & SS_ACCEPTCONN) == 0)
241 247 return (EINVAL);
242 248
243 249 error = so_acceptq_dequeue(so, (fflag & (FNONBLOCK|FNDELAY)), nsop);
244 250
245 251 return (error);
246 252 }
247 253
248 254 /*
249 255 * Bind local endpoint.
250 256 */
251 257 /*ARGSUSED*/
252 258 static int
253 259 sosctp_bind(struct sonode *so, struct sockaddr *name, socklen_t namelen,
254 260 int flags, struct cred *cr)
255 261 {
256 262 int error;
257 263
258 264 if (!(flags & _SOBIND_LOCK_HELD)) {
259 265 mutex_enter(&so->so_lock);
260 266 so_lock_single(so); /* Set SOLOCKED */
261 267 } else {
262 268 ASSERT(MUTEX_HELD(&so->so_lock));
263 269 }
264 270
265 271 /*
266 272 * X/Open requires this check
267 273 */
268 274 if (so->so_state & SS_CANTSENDMORE) {
269 275 error = EINVAL;
270 276 goto done;
271 277 }
272 278
273 279
274 280 /*
275 281 * Protocol module does address family checks.
276 282 */
277 283 mutex_exit(&so->so_lock);
278 284
279 285 error = sctp_bind((struct sctp_s *)so->so_proto_handle, name, namelen);
280 286
281 287 mutex_enter(&so->so_lock);
282 288 if (error == 0) {
283 289 so->so_state |= SS_ISBOUND;
284 290 } else {
285 291 eprintsoline(so, error);
286 292 }
287 293 done:
288 294 if (!(flags & _SOBIND_LOCK_HELD)) {
289 295 so_unlock_single(so, SOLOCKED);
290 296 mutex_exit(&so->so_lock);
291 297 } else {
292 298 /* If the caller held the lock don't release it here */
293 299 ASSERT(MUTEX_HELD(&so->so_lock));
294 300 ASSERT(so->so_flag & SOLOCKED);
295 301 }
296 302
297 303 return (error);
298 304 }
299 305
300 306 /*
301 307 * Turn socket into a listen socket.
302 308 */
303 309 /* ARGSUSED */
304 310 static int
305 311 sosctp_listen(struct sonode *so, int backlog, struct cred *cr)
306 312 {
307 313 int error = 0;
308 314
309 315 mutex_enter(&so->so_lock);
310 316 so_lock_single(so);
311 317
312 318 /*
313 319 * If this socket is trying to do connect, or if it has
314 320 * been connected, disallow.
315 321 */
316 322 if (so->so_state & (SS_ISCONNECTING | SS_ISCONNECTED |
317 323 SS_ISDISCONNECTING | SS_CANTRCVMORE | SS_CANTSENDMORE)) {
318 324 error = EINVAL;
319 325 eprintsoline(so, error);
320 326 goto done;
321 327 }
322 328
323 329 if (backlog < 0) {
324 330 backlog = 0;
325 331 }
326 332
327 333 /*
328 334 * If listen() is only called to change backlog, we don't
329 335 * need to notify protocol module.
330 336 */
331 337 if (so->so_state & SS_ACCEPTCONN) {
332 338 so->so_backlog = backlog;
333 339 goto done;
334 340 }
335 341
336 342 mutex_exit(&so->so_lock);
337 343 error = sctp_listen((struct sctp_s *)so->so_proto_handle);
338 344 mutex_enter(&so->so_lock);
339 345 if (error == 0) {
340 346 so->so_state |= (SS_ACCEPTCONN|SS_ISBOUND);
341 347 so->so_backlog = backlog;
342 348 } else {
343 349 eprintsoline(so, error);
344 350 }
345 351 done:
346 352 so_unlock_single(so, SOLOCKED);
347 353 mutex_exit(&so->so_lock);
348 354
349 355 return (error);
350 356 }
351 357
352 358 /*
353 359 * Active open.
354 360 */
355 361 /*ARGSUSED*/
356 362 static int
357 363 sosctp_connect(struct sonode *so, struct sockaddr *name,
358 364 socklen_t namelen, int fflag, int flags, struct cred *cr)
359 365 {
360 366 int error = 0;
361 367 pid_t pid = curproc->p_pid;
362 368
363 369 ASSERT(so->so_type == SOCK_STREAM);
364 370
365 371 mutex_enter(&so->so_lock);
366 372 so_lock_single(so);
367 373
368 374 /*
369 375 * Can't connect() after listen(), or if the socket is already
370 376 * connected.
371 377 */
372 378 if (so->so_state & (SS_ACCEPTCONN|SS_ISCONNECTED|SS_ISCONNECTING)) {
373 379 if (so->so_state & SS_ISCONNECTED) {
374 380 error = EISCONN;
375 381 } else if (so->so_state & SS_ISCONNECTING) {
376 382 error = EALREADY;
377 383 } else {
378 384 error = EOPNOTSUPP;
379 385 }
380 386 eprintsoline(so, error);
381 387 goto done;
382 388 }
383 389
384 390 /*
385 391 * Check for failure of an earlier call
386 392 */
387 393 if (so->so_error != 0) {
388 394 error = sogeterr(so, B_TRUE);
389 395 eprintsoline(so, error);
390 396 goto done;
391 397 }
392 398
393 399 /*
394 400 * Connection is closing, or closed, don't allow reconnect.
395 401 * TCP allows this to proceed, but the socket remains unwriteable.
396 402 * BSD returns EINVAL.
397 403 */
398 404 if (so->so_state & (SS_ISDISCONNECTING|SS_CANTRCVMORE|
399 405 SS_CANTSENDMORE)) {
400 406 error = EINVAL;
401 407 eprintsoline(so, error);
402 408 goto done;
403 409 }
404 410
405 411 if (name == NULL || namelen == 0) {
406 412 mutex_exit(&so->so_lock);
407 413 error = EINVAL;
408 414 eprintsoline(so, error);
409 415 goto done;
410 416 }
411 417
412 418 soisconnecting(so);
413 419 mutex_exit(&so->so_lock);
414 420
415 421 error = sctp_connect((struct sctp_s *)so->so_proto_handle,
416 422 name, namelen, cr, pid);
417 423
418 424 mutex_enter(&so->so_lock);
419 425 if (error == 0) {
420 426 /*
421 427 * Allow other threads to access the socket
422 428 */
423 429 error = sowaitconnected(so, fflag, 0);
424 430 }
425 431 done:
426 432 so_unlock_single(so, SOLOCKED);
427 433 mutex_exit(&so->so_lock);
428 434 return (error);
429 435 }
430 436
431 437 /*
432 438 * Active open for 1-N sockets, create a new association and
433 439 * call connect on that.
434 440 * If there parent hasn't been bound yet (this is the first association),
435 441 * make it so.
436 442 */
437 443 static int
438 444 sosctp_seq_connect(struct sonode *so, struct sockaddr *name,
439 445 socklen_t namelen, int fflag, int flags, struct cred *cr)
440 446 {
441 447 struct sctp_soassoc *ssa;
442 448 struct sctp_sonode *ss;
443 449 int error;
444 450
445 451 ASSERT(so->so_type == SOCK_SEQPACKET);
446 452
447 453 mutex_enter(&so->so_lock);
448 454 so_lock_single(so);
449 455
450 456 if (name == NULL || namelen == 0) {
451 457 error = EINVAL;
452 458 eprintsoline(so, error);
453 459 goto done;
454 460 }
455 461
456 462 ss = SOTOSSO(so);
457 463
458 464 error = sosctp_assoc_createconn(ss, name, namelen, NULL, 0, fflag,
459 465 cr, &ssa);
460 466 if (error != 0) {
461 467 if ((error == EHOSTUNREACH) && (flags & _SOCONNECT_XPG4_2)) {
462 468 error = ENETUNREACH;
463 469 }
464 470 }
465 471 if (ssa != NULL) {
466 472 SSA_REFRELE(ss, ssa);
467 473 }
468 474
469 475 done:
470 476 so_unlock_single(so, SOLOCKED);
471 477 mutex_exit(&so->so_lock);
472 478 return (error);
473 479 }
474 480
475 481 /*
476 482 * Receive data.
477 483 */
478 484 /* ARGSUSED */
479 485 static int
480 486 sosctp_recvmsg(struct sonode *so, struct nmsghdr *msg, struct uio *uiop,
481 487 struct cred *cr)
482 488 {
483 489 struct sctp_sonode *ss = SOTOSSO(so);
484 490 struct sctp_soassoc *ssa = NULL;
485 491 int flags, error = 0;
486 492 struct T_unitdata_ind *tind;
487 493 ssize_t orig_resid = uiop->uio_resid;
488 494 int len, count, readcnt = 0;
489 495 socklen_t controllen, namelen;
490 496 void *opt;
491 497 mblk_t *mp;
492 498 rval_t rval;
493 499
494 500 controllen = msg->msg_controllen;
495 501 namelen = msg->msg_namelen;
496 502 flags = msg->msg_flags;
497 503 msg->msg_flags = 0;
498 504 msg->msg_controllen = 0;
499 505 msg->msg_namelen = 0;
500 506
501 507 if (so->so_type == SOCK_STREAM) {
502 508 if (!(so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING|
503 509 SS_CANTRCVMORE))) {
504 510 return (ENOTCONN);
505 511 }
506 512 } else {
507 513 /* NOTE: Will come here from vop_read() as well */
508 514 /* For 1-N socket, recv() cannot be used. */
509 515 if (namelen == 0)
510 516 return (EOPNOTSUPP);
511 517 /*
512 518 * If there are no associations, and no new connections are
513 519 * coming in, there's not going to be new messages coming
514 520 * in either.
515 521 */
516 522 if (so->so_rcv_q_head == NULL && so->so_rcv_head == NULL &&
517 523 ss->ss_assoccnt == 0 && !(so->so_state & SS_ACCEPTCONN)) {
518 524 return (ENOTCONN);
519 525 }
520 526 }
521 527
522 528 /*
523 529 * out-of-band data not supported.
524 530 */
525 531 if (flags & MSG_OOB) {
526 532 return (EOPNOTSUPP);
527 533 }
528 534
529 535 /*
530 536 * flag possibilities:
531 537 *
532 538 * MSG_PEEK Don't consume data
533 539 * MSG_WAITALL Wait for full quantity of data (ignored if MSG_PEEK)
534 540 * MSG_DONTWAIT Non-blocking (same as FNDELAY | FNONBLOCK)
535 541 *
536 542 * MSG_WAITALL can return less than the full buffer if either
537 543 *
538 544 * 1. we would block and we are non-blocking
539 545 * 2. a full message cannot be delivered
540 546 *
541 547 * Given that we always get a full message from proto below,
542 548 * MSG_WAITALL is not meaningful.
543 549 */
544 550
545 551 mutex_enter(&so->so_lock);
546 552
547 553 /*
548 554 * Allow just one reader at a time.
549 555 */
550 556 error = so_lock_read_intr(so,
551 557 uiop->uio_fmode | ((flags & MSG_DONTWAIT) ? FNONBLOCK : 0));
552 558 if (error) {
553 559 mutex_exit(&so->so_lock);
554 560 return (error);
555 561 }
556 562 mutex_exit(&so->so_lock);
557 563 again:
558 564 error = so_dequeue_msg(so, &mp, uiop, &rval, flags | MSG_DUPCTRL);
559 565 if (mp != NULL) {
560 566 if (so->so_type == SOCK_SEQPACKET) {
561 567 ssa = *(struct sctp_soassoc **)DB_BASE(mp);
562 568 }
563 569
564 570 tind = (struct T_unitdata_ind *)mp->b_rptr;
565 571
566 572 len = tind->SRC_length;
567 573
568 574 if (namelen > 0 && len > 0) {
569 575
570 576 opt = sogetoff(mp, tind->SRC_offset, len, 1);
571 577
572 578 ASSERT(opt != NULL);
573 579
574 580 msg->msg_name = kmem_alloc(len, KM_SLEEP);
575 581 msg->msg_namelen = len;
576 582
577 583 bcopy(opt, msg->msg_name, len);
578 584 }
579 585
580 586 len = tind->OPT_length;
581 587 if (controllen == 0) {
582 588 if (len > 0) {
583 589 msg->msg_flags |= MSG_CTRUNC;
584 590 }
585 591 } else if (len > 0) {
586 592 opt = sogetoff(mp, tind->OPT_offset, len,
587 593 __TPI_ALIGN_SIZE);
588 594
589 595 ASSERT(opt != NULL);
590 596 sosctp_pack_cmsg(opt, msg, len);
591 597 }
592 598
593 599 if (mp->b_flag & SCTP_NOTIFICATION) {
594 600 msg->msg_flags |= MSG_NOTIFICATION;
595 601 }
596 602
597 603 if (!(mp->b_flag & SCTP_PARTIAL_DATA) &&
598 604 !(rval.r_val1 & MOREDATA)) {
599 605 msg->msg_flags |= MSG_EOR;
600 606 }
601 607 freemsg(mp);
602 608 }
603 609 done:
604 610 if (!(flags & MSG_PEEK))
605 611 readcnt = orig_resid - uiop->uio_resid;
606 612 /*
607 613 * Determine if we need to update SCTP about the buffer
608 614 * space. For performance reason, we cannot update SCTP
609 615 * every time a message is read. The socket buffer low
610 616 * watermark is used as the threshold.
611 617 */
612 618 if (ssa == NULL) {
613 619 mutex_enter(&so->so_lock);
614 620 count = so->so_rcvbuf - so->so_rcv_queued;
615 621
616 622 ASSERT(so->so_rcv_q_head != NULL ||
617 623 so->so_rcv_head != NULL ||
618 624 so->so_rcv_queued == 0);
619 625
620 626 so_unlock_read(so);
621 627
622 628 /*
623 629 * so_dequeue_msg() sets r_val2 to true if flow control was
624 630 * cleared and we need to update SCTP. so_flowctrld was
625 631 * cleared in so_dequeue_msg() via so_check_flow_control().
626 632 */
627 633 if (rval.r_val2) {
628 634 mutex_exit(&so->so_lock);
629 635 sctp_recvd((struct sctp_s *)so->so_proto_handle, count);
630 636 } else {
631 637 mutex_exit(&so->so_lock);
632 638 }
633 639 } else {
634 640 /*
635 641 * Each association keeps track of how much data it has
636 642 * queued; we need to update the value here. Note that this
637 643 * is slightly different from SOCK_STREAM type sockets, which
638 644 * does not need to update the byte count, as it is already
639 645 * done in so_dequeue_msg().
640 646 */
641 647 mutex_enter(&so->so_lock);
642 648 ssa->ssa_rcv_queued -= readcnt;
643 649 count = so->so_rcvbuf - ssa->ssa_rcv_queued;
644 650
645 651 so_unlock_read(so);
646 652
647 653 if (readcnt > 0 && ssa->ssa_flowctrld &&
648 654 ssa->ssa_rcv_queued < so->so_rcvlowat) {
649 655 /*
650 656 * Need to clear ssa_flowctrld, different from 1-1
651 657 * style.
652 658 */
653 659 ssa->ssa_flowctrld = B_FALSE;
654 660 mutex_exit(&so->so_lock);
655 661 sctp_recvd(ssa->ssa_conn, count);
656 662 mutex_enter(&so->so_lock);
657 663 }
658 664
659 665 /*
660 666 * MOREDATA flag is set if all data could not be copied
661 667 */
662 668 if (!(flags & MSG_PEEK) && !(rval.r_val1 & MOREDATA)) {
663 669 SSA_REFRELE(ss, ssa);
664 670 }
665 671 mutex_exit(&so->so_lock);
666 672 }
667 673
668 674 return (error);
669 675 }
670 676
671 677 int
672 678 sosctp_uiomove(mblk_t *hdr_mp, ssize_t count, ssize_t blk_size, int wroff,
673 679 struct uio *uiop, int flags)
674 680 {
675 681 ssize_t size;
676 682 int error;
677 683 mblk_t *mp;
678 684 dblk_t *dp;
679 685
680 686 if (blk_size == INFPSZ)
681 687 blk_size = count;
682 688
683 689 /*
684 690 * Loop until we have all data copied into mblk's.
685 691 */
686 692 while (count > 0) {
687 693 size = MIN(count, blk_size);
688 694
689 695 /*
690 696 * As a message can be splitted up and sent in different
691 697 * packets, each mblk will have the extra space before
692 698 * data to accommodate what SCTP wants to put in there.
693 699 */
694 700 while ((mp = allocb(size + wroff, BPRI_MED)) == NULL) {
695 701 if ((uiop->uio_fmode & (FNDELAY|FNONBLOCK)) ||
696 702 (flags & MSG_DONTWAIT)) {
697 703 return (EAGAIN);
698 704 }
699 705 if ((error = strwaitbuf(size + wroff, BPRI_MED))) {
700 706 return (error);
701 707 }
702 708 }
703 709
704 710 dp = mp->b_datap;
705 711 dp->db_cpid = curproc->p_pid;
706 712 ASSERT(wroff <= dp->db_lim - mp->b_wptr);
707 713 mp->b_rptr += wroff;
708 714 error = uiomove(mp->b_rptr, size, UIO_WRITE, uiop);
709 715 if (error != 0) {
710 716 freeb(mp);
711 717 return (error);
712 718 }
713 719 mp->b_wptr = mp->b_rptr + size;
714 720 count -= size;
715 721 hdr_mp->b_cont = mp;
716 722 hdr_mp = mp;
717 723 }
718 724 return (0);
719 725 }
720 726
721 727 /*
722 728 * Send message.
723 729 */
724 730 static int
725 731 sosctp_sendmsg(struct sonode *so, struct nmsghdr *msg, struct uio *uiop,
726 732 struct cred *cr)
727 733 {
728 734 mblk_t *mctl;
729 735 struct cmsghdr *cmsg;
730 736 struct sctp_sndrcvinfo *sinfo;
731 737 int optlen, flags, fflag;
732 738 ssize_t count, msglen;
733 739 int error;
734 740
735 741 ASSERT(so->so_type == SOCK_STREAM);
736 742
737 743 flags = msg->msg_flags;
738 744 if (flags & MSG_OOB) {
739 745 /*
740 746 * No out-of-band data support.
741 747 */
742 748 return (EOPNOTSUPP);
743 749 }
744 750
745 751 if (msg->msg_controllen != 0) {
746 752 optlen = msg->msg_controllen;
747 753 cmsg = sosctp_find_cmsg(msg->msg_control, optlen, SCTP_SNDRCV);
748 754 if (cmsg != NULL) {
749 755 if (cmsg->cmsg_len <
750 756 (sizeof (*sinfo) + sizeof (*cmsg))) {
751 757 eprintsoline(so, EINVAL);
752 758 return (EINVAL);
753 759 }
754 760 sinfo = (struct sctp_sndrcvinfo *)(cmsg + 1);
755 761
756 762 /* Both flags should not be set together. */
757 763 if ((sinfo->sinfo_flags & MSG_EOF) &&
758 764 (sinfo->sinfo_flags & MSG_ABORT)) {
759 765 eprintsoline(so, EINVAL);
760 766 return (EINVAL);
761 767 }
762 768
763 769 /* Initiate a graceful shutdown. */
764 770 if (sinfo->sinfo_flags & MSG_EOF) {
765 771 /* Can't include data in MSG_EOF message. */
766 772 if (uiop->uio_resid != 0) {
767 773 eprintsoline(so, EINVAL);
768 774 return (EINVAL);
769 775 }
770 776
771 777 /*
772 778 * This is the same sequence as done in
773 779 * shutdown(SHUT_WR).
774 780 */
775 781 mutex_enter(&so->so_lock);
776 782 so_lock_single(so);
777 783 socantsendmore(so);
778 784 cv_broadcast(&so->so_snd_cv);
779 785 so->so_state |= SS_ISDISCONNECTING;
780 786 mutex_exit(&so->so_lock);
781 787
782 788 pollwakeup(&so->so_poll_list, POLLOUT);
783 789 sctp_recvd((struct sctp_s *)so->so_proto_handle,
784 790 so->so_rcvbuf);
785 791 error = sctp_disconnect(
786 792 (struct sctp_s *)so->so_proto_handle);
787 793
788 794 mutex_enter(&so->so_lock);
789 795 so_unlock_single(so, SOLOCKED);
790 796 mutex_exit(&so->so_lock);
791 797 return (error);
792 798 }
793 799 }
794 800 } else {
795 801 optlen = 0;
796 802 }
797 803
798 804 mutex_enter(&so->so_lock);
799 805 for (;;) {
800 806 if (so->so_state & SS_CANTSENDMORE) {
801 807 mutex_exit(&so->so_lock);
802 808 return (EPIPE);
803 809 }
804 810
805 811 if (so->so_error != 0) {
806 812 error = sogeterr(so, B_TRUE);
807 813 mutex_exit(&so->so_lock);
808 814 return (error);
809 815 }
810 816
811 817 if (!so->so_snd_qfull)
812 818 break;
813 819
814 820 if (so->so_state & SS_CLOSING) {
815 821 mutex_exit(&so->so_lock);
816 822 return (EINTR);
817 823 }
818 824 /*
819 825 * Xmit window full in a blocking socket.
820 826 */
821 827 if ((uiop->uio_fmode & (FNDELAY|FNONBLOCK)) ||
822 828 (flags & MSG_DONTWAIT)) {
823 829 mutex_exit(&so->so_lock);
824 830 return (EAGAIN);
825 831 } else {
826 832 /*
827 833 * Wait for space to become available and try again.
828 834 */
829 835 error = cv_wait_sig(&so->so_snd_cv, &so->so_lock);
830 836 if (!error) { /* signal */
831 837 mutex_exit(&so->so_lock);
832 838 return (EINTR);
833 839 }
834 840 }
835 841 }
836 842 msglen = count = uiop->uio_resid;
837 843
838 844 /* Don't allow sending a message larger than the send buffer size. */
839 845 /* XXX Transport module need to enforce this */
840 846 if (msglen > so->so_sndbuf) {
841 847 mutex_exit(&so->so_lock);
842 848 return (EMSGSIZE);
843 849 }
844 850
845 851 /*
846 852 * Allow piggybacking data on handshake messages (SS_ISCONNECTING).
847 853 */
848 854 if (!(so->so_state & (SS_ISCONNECTING | SS_ISCONNECTED))) {
849 855 /*
850 856 * We need to check here for listener so that the
851 857 * same error will be returned as with a TCP socket.
852 858 * In this case, sosctp_connect() returns EOPNOTSUPP
853 859 * while a TCP socket returns ENOTCONN instead. Catch it
854 860 * here to have the same behavior as a TCP socket.
855 861 *
856 862 * We also need to make sure that the peer address is
857 863 * provided before we attempt to do the connect.
858 864 */
859 865 if ((so->so_state & SS_ACCEPTCONN) ||
860 866 msg->msg_name == NULL) {
861 867 mutex_exit(&so->so_lock);
862 868 error = ENOTCONN;
863 869 goto error_nofree;
864 870 }
865 871 mutex_exit(&so->so_lock);
866 872 fflag = uiop->uio_fmode;
867 873 if (flags & MSG_DONTWAIT) {
868 874 fflag |= FNDELAY;
869 875 }
870 876 error = sosctp_connect(so, msg->msg_name, msg->msg_namelen,
871 877 fflag, (so->so_version == SOV_XPG4_2) * _SOCONNECT_XPG4_2,
872 878 cr);
873 879 if (error) {
874 880 /*
875 881 * Check for non-fatal errors, socket connected
876 882 * while the lock had been lifted.
877 883 */
878 884 if (error != EISCONN && error != EALREADY) {
879 885 goto error_nofree;
880 886 }
881 887 error = 0;
882 888 }
883 889 } else {
884 890 mutex_exit(&so->so_lock);
885 891 }
886 892
887 893 mctl = sctp_alloc_hdr(msg->msg_name, msg->msg_namelen,
888 894 msg->msg_control, optlen, SCTP_CAN_BLOCK);
889 895 if (mctl == NULL) {
890 896 error = EINTR;
891 897 goto error_nofree;
892 898 }
893 899
894 900 /* Copy in the message. */
895 901 if ((error = sosctp_uiomove(mctl, count, so->so_proto_props.sopp_maxblk,
896 902 so->so_proto_props.sopp_wroff, uiop, flags)) != 0) {
897 903 goto error_ret;
898 904 }
899 905 error = sctp_sendmsg((struct sctp_s *)so->so_proto_handle, mctl, 0);
900 906 if (error == 0)
901 907 return (0);
902 908
903 909 error_ret:
904 910 freemsg(mctl);
905 911 error_nofree:
906 912 mutex_enter(&so->so_lock);
907 913 if ((error == EPIPE) && (so->so_state & SS_CANTSENDMORE)) {
908 914 /*
909 915 * We received shutdown between the time lock was
910 916 * lifted and call to sctp_sendmsg().
911 917 */
912 918 mutex_exit(&so->so_lock);
913 919 return (EPIPE);
914 920 }
915 921 mutex_exit(&so->so_lock);
916 922 return (error);
917 923 }
918 924
919 925 /*
920 926 * Send message on 1-N socket. Connects automatically if there is
921 927 * no association.
922 928 */
923 929 static int
924 930 sosctp_seq_sendmsg(struct sonode *so, struct nmsghdr *msg, struct uio *uiop,
925 931 struct cred *cr)
926 932 {
927 933 struct sctp_sonode *ss;
928 934 struct sctp_soassoc *ssa;
929 935 struct cmsghdr *cmsg;
930 936 struct sctp_sndrcvinfo *sinfo;
931 937 int aid = 0;
932 938 mblk_t *mctl;
933 939 int namelen, optlen, flags;
934 940 ssize_t count, msglen;
935 941 int error;
936 942 uint16_t s_flags = 0;
937 943
938 944 ASSERT(so->so_type == SOCK_SEQPACKET);
939 945
940 946 /*
941 947 * There shouldn't be problems with alignment, as the memory for
942 948 * msg_control was alloced with kmem_alloc.
943 949 */
944 950 cmsg = sosctp_find_cmsg(msg->msg_control, msg->msg_controllen,
945 951 SCTP_SNDRCV);
946 952 if (cmsg != NULL) {
947 953 if (cmsg->cmsg_len < (sizeof (*sinfo) + sizeof (*cmsg))) {
948 954 eprintsoline(so, EINVAL);
949 955 return (EINVAL);
950 956 }
951 957 sinfo = (struct sctp_sndrcvinfo *)(cmsg + 1);
952 958 s_flags = sinfo->sinfo_flags;
953 959 aid = sinfo->sinfo_assoc_id;
954 960 }
955 961
956 962 ss = SOTOSSO(so);
957 963 namelen = msg->msg_namelen;
958 964
959 965 if (msg->msg_controllen > 0) {
960 966 optlen = msg->msg_controllen;
961 967 } else {
962 968 optlen = 0;
963 969 }
964 970
965 971 mutex_enter(&so->so_lock);
966 972
967 973 /*
968 974 * If there is no association id, connect to address specified
969 975 * in msg_name. Otherwise look up the association using the id.
970 976 */
971 977 if (aid == 0) {
972 978 /*
973 979 * Connect and shutdown cannot be done together, so check for
974 980 * MSG_EOF.
975 981 */
976 982 if (msg->msg_name == NULL || namelen == 0 ||
977 983 (s_flags & MSG_EOF)) {
978 984 error = EINVAL;
979 985 eprintsoline(so, error);
980 986 goto done;
981 987 }
982 988 flags = uiop->uio_fmode;
983 989 if (msg->msg_flags & MSG_DONTWAIT) {
984 990 flags |= FNDELAY;
985 991 }
986 992 so_lock_single(so);
987 993 error = sosctp_assoc_createconn(ss, msg->msg_name, namelen,
988 994 msg->msg_control, optlen, flags, cr, &ssa);
989 995 if (error) {
990 996 if ((so->so_version == SOV_XPG4_2) &&
991 997 (error == EHOSTUNREACH)) {
992 998 error = ENETUNREACH;
993 999 }
994 1000 if (ssa == NULL) {
995 1001 /*
996 1002 * Fatal error during connect(). Bail out.
997 1003 * If ssa exists, it means that the handshake
998 1004 * is in progress.
999 1005 */
1000 1006 eprintsoline(so, error);
1001 1007 so_unlock_single(so, SOLOCKED);
1002 1008 goto done;
1003 1009 }
1004 1010 /*
1005 1011 * All the errors are non-fatal ones, don't return
1006 1012 * e.g. EINPROGRESS from sendmsg().
1007 1013 */
1008 1014 error = 0;
1009 1015 }
1010 1016 so_unlock_single(so, SOLOCKED);
1011 1017 } else {
1012 1018 if ((error = sosctp_assoc(ss, aid, &ssa)) != 0) {
1013 1019 eprintsoline(so, error);
1014 1020 goto done;
1015 1021 }
1016 1022 }
1017 1023
1018 1024 /*
1019 1025 * Now we have an association.
1020 1026 */
1021 1027 flags = msg->msg_flags;
1022 1028
1023 1029 /*
1024 1030 * MSG_EOF initiates graceful shutdown.
1025 1031 */
1026 1032 if (s_flags & MSG_EOF) {
1027 1033 if (uiop->uio_resid) {
1028 1034 /*
1029 1035 * Can't include data in MSG_EOF message.
1030 1036 */
1031 1037 error = EINVAL;
1032 1038 } else {
1033 1039 mutex_exit(&so->so_lock);
1034 1040 ssa->ssa_state |= SS_ISDISCONNECTING;
1035 1041 sctp_recvd(ssa->ssa_conn, so->so_rcvbuf);
1036 1042 error = sctp_disconnect(ssa->ssa_conn);
1037 1043 mutex_enter(&so->so_lock);
1038 1044 }
1039 1045 goto refrele;
1040 1046 }
1041 1047
1042 1048 for (;;) {
1043 1049 if (ssa->ssa_state & SS_CANTSENDMORE) {
1044 1050 SSA_REFRELE(ss, ssa);
1045 1051 mutex_exit(&so->so_lock);
1046 1052 return (EPIPE);
1047 1053 }
1048 1054 if (ssa->ssa_error != 0) {
1049 1055 error = ssa->ssa_error;
1050 1056 ssa->ssa_error = 0;
1051 1057 goto refrele;
1052 1058 }
1053 1059
1054 1060 if (!ssa->ssa_snd_qfull)
1055 1061 break;
1056 1062
1057 1063 if (so->so_state & SS_CLOSING) {
1058 1064 error = EINTR;
1059 1065 goto refrele;
1060 1066 }
1061 1067 if ((uiop->uio_fmode & (FNDELAY|FNONBLOCK)) ||
1062 1068 (flags & MSG_DONTWAIT)) {
1063 1069 error = EAGAIN;
1064 1070 goto refrele;
1065 1071 } else {
1066 1072 /*
1067 1073 * Wait for space to become available and try again.
1068 1074 */
1069 1075 error = cv_wait_sig(&so->so_snd_cv, &so->so_lock);
1070 1076 if (!error) { /* signal */
1071 1077 error = EINTR;
1072 1078 goto refrele;
1073 1079 }
1074 1080 }
1075 1081 }
1076 1082
1077 1083 msglen = count = uiop->uio_resid;
1078 1084
1079 1085 /* Don't allow sending a message larger than the send buffer size. */
1080 1086 if (msglen > so->so_sndbuf) {
1081 1087 error = EMSGSIZE;
1082 1088 goto refrele;
1083 1089 }
1084 1090
1085 1091 /*
1086 1092 * Update TX buffer usage here so that we can lift the socket lock.
1087 1093 */
1088 1094 mutex_exit(&so->so_lock);
1089 1095
1090 1096 mctl = sctp_alloc_hdr(msg->msg_name, namelen, msg->msg_control,
1091 1097 optlen, SCTP_CAN_BLOCK);
1092 1098 if (mctl == NULL) {
1093 1099 error = EINTR;
1094 1100 goto lock_rele;
1095 1101 }
1096 1102
1097 1103 /* Copy in the message. */
1098 1104 if ((error = sosctp_uiomove(mctl, count, ssa->ssa_wrsize,
1099 1105 ssa->ssa_wroff, uiop, flags)) != 0) {
1100 1106 goto lock_rele;
1101 1107 }
1102 1108 error = sctp_sendmsg((struct sctp_s *)ssa->ssa_conn, mctl, 0);
1103 1109 lock_rele:
1104 1110 mutex_enter(&so->so_lock);
1105 1111 if (error != 0) {
1106 1112 freemsg(mctl);
1107 1113 if ((error == EPIPE) && (ssa->ssa_state & SS_CANTSENDMORE)) {
1108 1114 /*
1109 1115 * We received shutdown between the time lock was
1110 1116 * lifted and call to sctp_sendmsg().
1111 1117 */
1112 1118 SSA_REFRELE(ss, ssa);
1113 1119 mutex_exit(&so->so_lock);
1114 1120 return (EPIPE);
1115 1121 }
1116 1122 }
1117 1123
1118 1124 refrele:
1119 1125 SSA_REFRELE(ss, ssa);
1120 1126 done:
1121 1127 mutex_exit(&so->so_lock);
1122 1128 return (error);
1123 1129 }
1124 1130
1125 1131 /*
1126 1132 * Get address of remote node.
1127 1133 */
1128 1134 /* ARGSUSED */
1129 1135 static int
1130 1136 sosctp_getpeername(struct sonode *so, struct sockaddr *addr, socklen_t *addrlen,
1131 1137 boolean_t accept, struct cred *cr)
1132 1138 {
1133 1139 return (sctp_getpeername((struct sctp_s *)so->so_proto_handle, addr,
1134 1140 addrlen));
1135 1141 }
1136 1142
1137 1143 /*
1138 1144 * Get local address.
1139 1145 */
1140 1146 /* ARGSUSED */
1141 1147 static int
1142 1148 sosctp_getsockname(struct sonode *so, struct sockaddr *addr, socklen_t *addrlen,
1143 1149 struct cred *cr)
1144 1150 {
1145 1151 return (sctp_getsockname((struct sctp_s *)so->so_proto_handle, addr,
1146 1152 addrlen));
1147 1153 }
1148 1154
1149 1155 /*
1150 1156 * Called from shutdown().
1151 1157 */
1152 1158 /* ARGSUSED */
1153 1159 static int
1154 1160 sosctp_shutdown(struct sonode *so, int how, struct cred *cr)
1155 1161 {
1156 1162 uint_t state_change;
1157 1163 int wakesig = 0;
1158 1164 int error = 0;
1159 1165
1160 1166 mutex_enter(&so->so_lock);
1161 1167 /*
1162 1168 * Record the current state and then perform any state changes.
1163 1169 * Then use the difference between the old and new states to
1164 1170 * determine which needs to be done.
1165 1171 */
1166 1172 state_change = so->so_state;
1167 1173
1168 1174 switch (how) {
1169 1175 case SHUT_RD:
1170 1176 socantrcvmore(so);
1171 1177 break;
1172 1178 case SHUT_WR:
1173 1179 socantsendmore(so);
1174 1180 break;
1175 1181 case SHUT_RDWR:
1176 1182 socantsendmore(so);
1177 1183 socantrcvmore(so);
1178 1184 break;
1179 1185 default:
1180 1186 mutex_exit(&so->so_lock);
1181 1187 return (EINVAL);
1182 1188 }
1183 1189
1184 1190 state_change = so->so_state & ~state_change;
1185 1191
1186 1192 if (state_change & SS_CANTRCVMORE) {
1187 1193 if (so->so_rcv_q_head == NULL) {
1188 1194 cv_signal(&so->so_rcv_cv);
1189 1195 }
1190 1196 wakesig = POLLIN|POLLRDNORM;
1191 1197
1192 1198 socket_sendsig(so, SOCKETSIG_READ);
1193 1199 }
1194 1200 if (state_change & SS_CANTSENDMORE) {
1195 1201 cv_broadcast(&so->so_snd_cv);
1196 1202 wakesig |= POLLOUT;
1197 1203
1198 1204 so->so_state |= SS_ISDISCONNECTING;
1199 1205 }
1200 1206 mutex_exit(&so->so_lock);
1201 1207
1202 1208 pollwakeup(&so->so_poll_list, wakesig);
1203 1209
1204 1210 if (state_change & SS_CANTSENDMORE) {
1205 1211 sctp_recvd((struct sctp_s *)so->so_proto_handle, so->so_rcvbuf);
1206 1212 error = sctp_disconnect((struct sctp_s *)so->so_proto_handle);
1207 1213 }
1208 1214
1209 1215 /*
1210 1216 * HACK: sctp_disconnect() may return EWOULDBLOCK. But this error is
1211 1217 * not documented in standard socket API. Catch it here.
1212 1218 */
1213 1219 if (error == EWOULDBLOCK)
1214 1220 error = 0;
1215 1221 return (error);
1216 1222 }
1217 1223
1218 1224 /*
1219 1225 * Get socket options.
1220 1226 */
1221 1227 /*ARGSUSED5*/
1222 1228 static int
1223 1229 sosctp_getsockopt(struct sonode *so, int level, int option_name,
1224 1230 void *optval, socklen_t *optlenp, int flags, struct cred *cr)
1225 1231 {
1226 1232 socklen_t maxlen = *optlenp;
1227 1233 socklen_t len;
1228 1234 socklen_t optlen;
1229 1235 uint8_t buffer[4];
1230 1236 void *optbuf = &buffer;
1231 1237 int error = 0;
1232 1238
1233 1239 if (level == SOL_SOCKET) {
1234 1240 switch (option_name) {
1235 1241 /* Not supported options */
1236 1242 case SO_SNDTIMEO:
1237 1243 case SO_RCVTIMEO:
1238 1244 case SO_EXCLBIND:
1239 1245 eprintsoline(so, ENOPROTOOPT);
1240 1246 return (ENOPROTOOPT);
1241 1247 default:
1242 1248 error = socket_getopt_common(so, level, option_name,
1243 1249 optval, optlenp, flags);
1244 1250 if (error >= 0)
1245 1251 return (error);
1246 1252 /* Pass the request to the protocol */
1247 1253 break;
1248 1254 }
1249 1255 }
1250 1256
1251 1257 if (level == IPPROTO_SCTP) {
1252 1258 /*
1253 1259 * Should go through ioctl().
1254 1260 */
1255 1261 return (EINVAL);
1256 1262 }
1257 1263
1258 1264 if (maxlen > sizeof (buffer)) {
1259 1265 optbuf = kmem_alloc(maxlen, KM_SLEEP);
1260 1266 }
1261 1267 optlen = maxlen;
1262 1268
1263 1269 /*
1264 1270 * If the resulting optlen is greater than the provided maxlen, then
1265 1271 * we sliently trucate.
1266 1272 */
1267 1273 error = sctp_get_opt((struct sctp_s *)so->so_proto_handle, level,
1268 1274 option_name, optbuf, &optlen);
1269 1275
1270 1276 if (error != 0) {
1271 1277 eprintsoline(so, error);
1272 1278 goto free;
1273 1279 }
1274 1280 len = optlen;
1275 1281
1276 1282 copyout:
1277 1283
1278 1284 len = MIN(len, maxlen);
1279 1285 bcopy(optbuf, optval, len);
1280 1286 *optlenp = optlen;
1281 1287 free:
1282 1288 if (optbuf != &buffer) {
1283 1289 kmem_free(optbuf, maxlen);
1284 1290 }
1285 1291
1286 1292 return (error);
1287 1293 }
1288 1294
1289 1295 /*
1290 1296 * Set socket options
1291 1297 */
1292 1298 /* ARGSUSED */
1293 1299 static int
1294 1300 sosctp_setsockopt(struct sonode *so, int level, int option_name,
1295 1301 const void *optval, t_uscalar_t optlen, struct cred *cr)
1296 1302 {
1297 1303 struct sctp_sonode *ss = SOTOSSO(so);
1298 1304 struct sctp_soassoc *ssa = NULL;
1299 1305 sctp_assoc_t id;
1300 1306 int error, rc;
1301 1307 void *conn = NULL;
1302 1308
1303 1309 mutex_enter(&so->so_lock);
1304 1310
1305 1311 /*
1306 1312 * For some SCTP level options, one can select the association this
1307 1313 * applies to.
1308 1314 */
1309 1315 if (so->so_type == SOCK_STREAM) {
1310 1316 conn = so->so_proto_handle;
1311 1317 } else {
1312 1318 /*
1313 1319 * SOCK_SEQPACKET only
1314 1320 */
1315 1321 id = 0;
1316 1322 if (level == IPPROTO_SCTP) {
1317 1323 switch (option_name) {
1318 1324 case SCTP_RTOINFO:
1319 1325 case SCTP_ASSOCINFO:
1320 1326 case SCTP_SET_PEER_PRIMARY_ADDR:
1321 1327 case SCTP_PRIMARY_ADDR:
1322 1328 case SCTP_PEER_ADDR_PARAMS:
1323 1329 /*
1324 1330 * Association ID is the first element
1325 1331 * params struct
1326 1332 */
1327 1333 if (optlen < sizeof (sctp_assoc_t)) {
1328 1334 error = EINVAL;
1329 1335 eprintsoline(so, error);
1330 1336 goto done;
1331 1337 }
1332 1338 id = *(sctp_assoc_t *)optval;
1333 1339 break;
1334 1340 case SCTP_DEFAULT_SEND_PARAM:
1335 1341 if (optlen != sizeof (struct sctp_sndrcvinfo)) {
1336 1342 error = EINVAL;
1337 1343 eprintsoline(so, error);
1338 1344 goto done;
1339 1345 }
1340 1346 id = ((struct sctp_sndrcvinfo *)
1341 1347 optval)->sinfo_assoc_id;
1342 1348 break;
1343 1349 case SCTP_INITMSG:
1344 1350 /*
1345 1351 * Only applies to future associations
1346 1352 */
1347 1353 conn = so->so_proto_handle;
1348 1354 break;
1349 1355 default:
1350 1356 break;
1351 1357 }
1352 1358 } else if (level == SOL_SOCKET) {
1353 1359 if (option_name == SO_LINGER) {
1354 1360 error = EOPNOTSUPP;
1355 1361 eprintsoline(so, error);
1356 1362 goto done;
1357 1363 }
1358 1364 /*
1359 1365 * These 2 options are applied to all associations.
1360 1366 * The other socket level options are only applied
1361 1367 * to the socket (not associations).
1362 1368 */
1363 1369 if ((option_name != SO_RCVBUF) &&
1364 1370 (option_name != SO_SNDBUF)) {
1365 1371 conn = so->so_proto_handle;
1366 1372 }
1367 1373 } else {
1368 1374 conn = NULL;
1369 1375 }
1370 1376
1371 1377 /*
1372 1378 * If association ID was specified, do op on that assoc.
1373 1379 * Otherwise set the default setting of a socket.
1374 1380 */
1375 1381 if (id != 0) {
1376 1382 if ((error = sosctp_assoc(ss, id, &ssa)) != 0) {
1377 1383 eprintsoline(so, error);
1378 1384 goto done;
1379 1385 }
1380 1386 conn = ssa->ssa_conn;
1381 1387 }
1382 1388 }
1383 1389 dprint(2, ("sosctp_setsockopt %p (%d) - conn %p %d %d id:%d\n",
1384 1390 (void *)ss, so->so_type, (void *)conn, level, option_name, id));
1385 1391
1386 1392 ASSERT(ssa == NULL || (ssa != NULL && conn != NULL));
1387 1393 if (conn != NULL) {
1388 1394 mutex_exit(&so->so_lock);
1389 1395 error = sctp_set_opt((struct sctp_s *)conn, level, option_name,
1390 1396 optval, optlen);
1391 1397 mutex_enter(&so->so_lock);
1392 1398 if (ssa != NULL)
1393 1399 SSA_REFRELE(ss, ssa);
1394 1400 } else {
1395 1401 /*
1396 1402 * 1-N socket, and we have to apply the operation to ALL
1397 1403 * associations. Like with anything of this sort, the
1398 1404 * problem is what to do if the operation fails.
1399 1405 * Just try to apply the setting to everyone, but store
1400 1406 * error number if someone returns such. And since we are
1401 1407 * looping through all possible aids, some of them can be
1402 1408 * invalid. We just ignore this kind (sosctp_assoc()) of
1403 1409 * errors.
1404 1410 */
1405 1411 sctp_assoc_t aid;
1406 1412
1407 1413 mutex_exit(&so->so_lock);
1408 1414 error = sctp_set_opt((struct sctp_s *)so->so_proto_handle,
1409 1415 level, option_name, optval, optlen);
1410 1416 mutex_enter(&so->so_lock);
1411 1417 for (aid = 1; aid < ss->ss_maxassoc; aid++) {
1412 1418 if (sosctp_assoc(ss, aid, &ssa) != 0)
1413 1419 continue;
1414 1420 mutex_exit(&so->so_lock);
1415 1421 rc = sctp_set_opt((struct sctp_s *)ssa->ssa_conn, level,
1416 1422 option_name, optval, optlen);
1417 1423 mutex_enter(&so->so_lock);
1418 1424 SSA_REFRELE(ss, ssa);
1419 1425 if (error == 0) {
1420 1426 error = rc;
1421 1427 }
1422 1428 }
1423 1429 }
1424 1430 done:
1425 1431 mutex_exit(&so->so_lock);
1426 1432 return (error);
1427 1433 }
1428 1434
1429 1435 /*ARGSUSED*/
1430 1436 static int
1431 1437 sosctp_ioctl(struct sonode *so, int cmd, intptr_t arg, int mode,
1432 1438 struct cred *cr, int32_t *rvalp)
1433 1439 {
1434 1440 struct sctp_sonode *ss;
1435 1441 int32_t value;
1436 1442 int error;
1437 1443 int intval;
1438 1444 pid_t pid;
1439 1445 struct sctp_soassoc *ssa;
1440 1446 void *conn;
1441 1447 void *buf;
1442 1448 STRUCT_DECL(sctpopt, opt);
1443 1449 uint32_t optlen;
1444 1450 int buflen;
1445 1451
1446 1452 ss = SOTOSSO(so);
1447 1453
1448 1454 /* handle socket specific ioctls */
1449 1455 switch (cmd) {
1450 1456 case FIONBIO:
1451 1457 if (so_copyin((void *)arg, &value, sizeof (int32_t),
1452 1458 (mode & (int)FKIOCTL))) {
1453 1459 return (EFAULT);
1454 1460 }
1455 1461 mutex_enter(&so->so_lock);
1456 1462 if (value) {
1457 1463 so->so_state |= SS_NDELAY;
1458 1464 } else {
1459 1465 so->so_state &= ~SS_NDELAY;
1460 1466 }
1461 1467 mutex_exit(&so->so_lock);
1462 1468 return (0);
1463 1469
1464 1470 case FIOASYNC:
1465 1471 if (so_copyin((void *)arg, &value, sizeof (int32_t),
1466 1472 (mode & (int)FKIOCTL))) {
1467 1473 return (EFAULT);
1468 1474 }
1469 1475 mutex_enter(&so->so_lock);
1470 1476
1471 1477 if (value) {
1472 1478 /* Turn on SIGIO */
1473 1479 so->so_state |= SS_ASYNC;
1474 1480 } else {
1475 1481 /* Turn off SIGIO */
1476 1482 so->so_state &= ~SS_ASYNC;
1477 1483 }
1478 1484 mutex_exit(&so->so_lock);
1479 1485 return (0);
1480 1486
1481 1487 case SIOCSPGRP:
1482 1488 case FIOSETOWN:
1483 1489 if (so_copyin((void *)arg, &pid, sizeof (pid_t),
1484 1490 (mode & (int)FKIOCTL))) {
1485 1491 return (EFAULT);
1486 1492 }
1487 1493 mutex_enter(&so->so_lock);
1488 1494
1489 1495 error = (pid != so->so_pgrp) ? socket_chgpgrp(so, pid) : 0;
1490 1496 mutex_exit(&so->so_lock);
1491 1497 return (error);
1492 1498
1493 1499 case SIOCGPGRP:
1494 1500 case FIOGETOWN:
1495 1501 if (so_copyout(&so->so_pgrp, (void *)arg,
1496 1502 sizeof (pid_t), (mode & (int)FKIOCTL)))
1497 1503 return (EFAULT);
1498 1504 return (0);
1499 1505
1500 1506 case FIONREAD:
1501 1507 /* XXX: Cannot be used unless standard buffer is used */
1502 1508 /*
1503 1509 * Return number of bytes of data in all data messages
1504 1510 * in queue in "arg".
1505 1511 * For stream socket, amount of available data.
1506 1512 * For sock_dgram, # of available bytes + addresses.
1507 1513 */
1508 1514 intval = (so->so_state & SS_ACCEPTCONN) ? 0 :
1509 1515 MIN(so->so_rcv_queued, INT_MAX);
1510 1516 if (so_copyout(&intval, (void *)arg, sizeof (intval),
1511 1517 (mode & (int)FKIOCTL)))
1512 1518 return (EFAULT);
1513 1519 return (0);
1514 1520 case SIOCATMARK:
1515 1521 /*
1516 1522 * No support for urgent data.
1517 1523 */
1518 1524 intval = 0;
1519 1525
1520 1526 if (so_copyout(&intval, (void *)arg, sizeof (int),
1521 1527 (mode & (int)FKIOCTL)))
1522 1528 return (EFAULT);
1523 1529 return (0);
1524 1530 case _I_GETPEERCRED: {
1525 1531 int error = 0;
1526 1532
1527 1533 if ((mode & FKIOCTL) == 0)
1528 1534 return (EINVAL);
1529 1535
1530 1536 mutex_enter(&so->so_lock);
1531 1537 if ((so->so_mode & SM_CONNREQUIRED) == 0) {
1532 1538 error = ENOTSUP;
1533 1539 } else if ((so->so_state & SS_ISCONNECTED) == 0) {
1534 1540 error = ENOTCONN;
1535 1541 } else if (so->so_peercred != NULL) {
1536 1542 k_peercred_t *kp = (k_peercred_t *)arg;
1537 1543 kp->pc_cr = so->so_peercred;
1538 1544 kp->pc_cpid = so->so_cpid;
1539 1545 crhold(so->so_peercred);
1540 1546 } else {
1541 1547 error = EINVAL;
1542 1548 }
1543 1549 mutex_exit(&so->so_lock);
1544 1550 return (error);
1545 1551 }
1546 1552 case SIOCSCTPGOPT:
1547 1553 STRUCT_INIT(opt, mode);
1548 1554
1549 1555 if (so_copyin((void *)arg, STRUCT_BUF(opt), STRUCT_SIZE(opt),
1550 1556 (mode & (int)FKIOCTL))) {
1551 1557 return (EFAULT);
1552 1558 }
1553 1559 if ((optlen = STRUCT_FGET(opt, sopt_len)) > SO_MAXARGSIZE)
1554 1560 return (EINVAL);
1555 1561
1556 1562 /*
1557 1563 * Find the correct sctp_t based on whether it is 1-N socket
1558 1564 * or not.
1559 1565 */
1560 1566 intval = STRUCT_FGET(opt, sopt_aid);
1561 1567 mutex_enter(&so->so_lock);
1562 1568 if ((so->so_type == SOCK_SEQPACKET) && intval) {
1563 1569 if ((error = sosctp_assoc(ss, intval, &ssa)) != 0) {
1564 1570 mutex_exit(&so->so_lock);
1565 1571 return (error);
1566 1572 }
1567 1573 conn = ssa->ssa_conn;
1568 1574 ASSERT(conn != NULL);
1569 1575 } else {
1570 1576 conn = so->so_proto_handle;
1571 1577 ssa = NULL;
1572 1578 }
1573 1579 mutex_exit(&so->so_lock);
1574 1580
1575 1581 /* Copyin the option buffer and then call sctp_get_opt(). */
1576 1582 buflen = optlen;
1577 1583 /* Let's allocate a buffer enough to hold an int */
1578 1584 if (buflen < sizeof (uint32_t))
1579 1585 buflen = sizeof (uint32_t);
1580 1586 buf = kmem_alloc(buflen, KM_SLEEP);
1581 1587 if (so_copyin(STRUCT_FGETP(opt, sopt_val), buf, optlen,
1582 1588 (mode & (int)FKIOCTL))) {
1583 1589 if (ssa != NULL) {
1584 1590 mutex_enter(&so->so_lock);
1585 1591 SSA_REFRELE(ss, ssa);
1586 1592 mutex_exit(&so->so_lock);
1587 1593 }
1588 1594 kmem_free(buf, buflen);
1589 1595 return (EFAULT);
1590 1596 }
1591 1597 /* The option level has to be IPPROTO_SCTP */
1592 1598 error = sctp_get_opt((struct sctp_s *)conn, IPPROTO_SCTP,
1593 1599 STRUCT_FGET(opt, sopt_name), buf, &optlen);
1594 1600 if (ssa != NULL) {
1595 1601 mutex_enter(&so->so_lock);
1596 1602 SSA_REFRELE(ss, ssa);
1597 1603 mutex_exit(&so->so_lock);
1598 1604 }
1599 1605 optlen = MIN(buflen, optlen);
1600 1606 /* No error, copyout the result with the correct buf len. */
1601 1607 if (error == 0) {
1602 1608 STRUCT_FSET(opt, sopt_len, optlen);
1603 1609 if (so_copyout(STRUCT_BUF(opt), (void *)arg,
1604 1610 STRUCT_SIZE(opt), (mode & (int)FKIOCTL))) {
1605 1611 error = EFAULT;
1606 1612 } else if (so_copyout(buf, STRUCT_FGETP(opt, sopt_val),
1607 1613 optlen, (mode & (int)FKIOCTL))) {
1608 1614 error = EFAULT;
1609 1615 }
1610 1616 }
1611 1617 kmem_free(buf, buflen);
1612 1618 return (error);
1613 1619
1614 1620 case SIOCSCTPSOPT:
1615 1621 STRUCT_INIT(opt, mode);
1616 1622
1617 1623 if (so_copyin((void *)arg, STRUCT_BUF(opt), STRUCT_SIZE(opt),
1618 1624 (mode & (int)FKIOCTL))) {
1619 1625 return (EFAULT);
1620 1626 }
1621 1627 if ((optlen = STRUCT_FGET(opt, sopt_len)) > SO_MAXARGSIZE)
1622 1628 return (EINVAL);
1623 1629
1624 1630 /*
1625 1631 * Find the correct sctp_t based on whether it is 1-N socket
1626 1632 * or not.
1627 1633 */
1628 1634 intval = STRUCT_FGET(opt, sopt_aid);
1629 1635 mutex_enter(&so->so_lock);
1630 1636 if (intval != 0) {
1631 1637 if ((error = sosctp_assoc(ss, intval, &ssa)) != 0) {
1632 1638 mutex_exit(&so->so_lock);
1633 1639 return (error);
1634 1640 }
1635 1641 conn = ssa->ssa_conn;
1636 1642 ASSERT(conn != NULL);
1637 1643 } else {
1638 1644 conn = so->so_proto_handle;
1639 1645 ssa = NULL;
1640 1646 }
1641 1647 mutex_exit(&so->so_lock);
1642 1648
1643 1649 /* Copyin the option buffer and then call sctp_set_opt(). */
1644 1650 buf = kmem_alloc(optlen, KM_SLEEP);
1645 1651 if (so_copyin(STRUCT_FGETP(opt, sopt_val), buf, optlen,
1646 1652 (mode & (int)FKIOCTL))) {
1647 1653 if (ssa != NULL) {
1648 1654 mutex_enter(&so->so_lock);
1649 1655 SSA_REFRELE(ss, ssa);
1650 1656 mutex_exit(&so->so_lock);
1651 1657 }
1652 1658 kmem_free(buf, intval);
1653 1659 return (EFAULT);
1654 1660 }
1655 1661 /* The option level has to be IPPROTO_SCTP */
1656 1662 error = sctp_set_opt((struct sctp_s *)conn, IPPROTO_SCTP,
1657 1663 STRUCT_FGET(opt, sopt_name), buf, optlen);
1658 1664 if (ssa) {
1659 1665 mutex_enter(&so->so_lock);
1660 1666 SSA_REFRELE(ss, ssa);
1661 1667 mutex_exit(&so->so_lock);
1662 1668 }
1663 1669 kmem_free(buf, optlen);
1664 1670 return (error);
1665 1671
1666 1672 case SIOCSCTPPEELOFF: {
1667 1673 struct sonode *nso;
1668 1674 struct sctp_uc_swap us;
1669 1675 int nfd;
1670 1676 struct file *nfp;
1671 1677 struct vnode *nvp = NULL;
1672 1678 struct sockparams *sp;
1673 1679
1674 1680 dprint(2, ("sctppeeloff %p\n", (void *)ss));
1675 1681
1676 1682 if (so->so_type != SOCK_SEQPACKET) {
1677 1683 return (EOPNOTSUPP);
1678 1684 }
1679 1685 if (so_copyin((void *)arg, &intval, sizeof (intval),
1680 1686 (mode & (int)FKIOCTL))) {
1681 1687 return (EFAULT);
1682 1688 }
1683 1689 if (intval == 0) {
1684 1690 return (EINVAL);
1685 1691 }
1686 1692
1687 1693 /*
1688 1694 * Find sockparams. This is different from parent's entry,
1689 1695 * as the socket type is different.
1690 1696 */
1691 1697 error = solookup(so->so_family, SOCK_STREAM, so->so_protocol,
1692 1698 &sp);
1693 1699 if (error != 0)
1694 1700 return (error);
1695 1701
1696 1702 /*
1697 1703 * Allocate the user fd.
1698 1704 */
1699 1705 if ((nfd = ufalloc(0)) == -1) {
1700 1706 eprintsoline(so, EMFILE);
1701 1707 SOCKPARAMS_DEC_REF(sp);
1702 1708 return (EMFILE);
1703 1709 }
1704 1710
1705 1711 /*
1706 1712 * Copy the fd out.
1707 1713 */
1708 1714 if (so_copyout(&nfd, (void *)arg, sizeof (nfd),
1709 1715 (mode & (int)FKIOCTL))) {
1710 1716 error = EFAULT;
1711 1717 goto err;
1712 1718 }
1713 1719 mutex_enter(&so->so_lock);
1714 1720
1715 1721 /*
1716 1722 * Don't use sosctp_assoc() in order to peel off disconnected
1717 1723 * associations.
1718 1724 */
1719 1725 ssa = ((uint32_t)intval >= ss->ss_maxassoc) ? NULL :
1720 1726 ss->ss_assocs[intval].ssi_assoc;
1721 1727 if (ssa == NULL) {
1722 1728 mutex_exit(&so->so_lock);
1723 1729 error = EINVAL;
1724 1730 goto err;
1725 1731 }
1726 1732 SSA_REFHOLD(ssa);
1727 1733
1728 1734 nso = socksctp_create(sp, so->so_family, SOCK_STREAM,
1729 1735 so->so_protocol, so->so_version, SOCKET_NOSLEEP,
1730 1736 &error, cr);
1731 1737 if (nso == NULL) {
1732 1738 SSA_REFRELE(ss, ssa);
1733 1739 mutex_exit(&so->so_lock);
1734 1740 goto err;
1735 1741 }
1736 1742 nvp = SOTOV(nso);
1737 1743 so_lock_single(so);
1738 1744 mutex_exit(&so->so_lock);
1739 1745
1740 1746 /* cannot fail, only inheriting properties */
1741 1747 (void) sosctp_init(nso, so, CRED(), 0);
1742 1748
1743 1749 /*
1744 1750 * We have a single ref on the new socket. This is normally
1745 1751 * handled by socket_{create,newconn}, but since they are not
1746 1752 * used we have to do it here.
1747 1753 */
1748 1754 nso->so_count = 1;
1749 1755
1750 1756 us.sus_handle = nso;
1751 1757 us.sus_upcalls = &sosctp_sock_upcalls;
1752 1758
1753 1759 /*
1754 1760 * Upcalls to new socket are blocked for the duration of
1755 1761 * downcall.
1756 1762 */
1757 1763 mutex_enter(&nso->so_lock);
1758 1764
1759 1765 error = sctp_set_opt((struct sctp_s *)ssa->ssa_conn,
1760 1766 IPPROTO_SCTP, SCTP_UC_SWAP, &us, sizeof (us));
1761 1767 if (error) {
1762 1768 goto peelerr;
1763 1769 }
1764 1770 error = falloc(nvp, FWRITE|FREAD, &nfp, NULL);
1765 1771 if (error) {
↓ open down ↓ |
1585 lines elided |
↑ open up ↑ |
1766 1772 goto peelerr;
1767 1773 }
1768 1774
1769 1775 /*
1770 1776 * fill in the entries that falloc reserved
1771 1777 */
1772 1778 nfp->f_vnode = nvp;
1773 1779 mutex_exit(&nfp->f_tlock);
1774 1780 setf(nfd, nfp);
1775 1781
1782 + /* add curproc to the pid list associated with that file */
1783 + if (nfp->f_vnode != NULL)
1784 + (void) VOP_IOCTL(nfp->f_vnode, F_FORKED,
1785 + (intptr_t)curproc, FKIOCTL, kcred, NULL, NULL);
1786 +
1776 1787 mutex_enter(&so->so_lock);
1777 1788
1778 1789 sosctp_assoc_move(ss, SOTOSSO(nso), ssa);
1779 1790
1780 1791 mutex_exit(&nso->so_lock);
1781 1792
1782 1793 ssa->ssa_conn = NULL;
1783 1794 sosctp_assoc_free(ss, ssa);
1784 1795
1785 1796 so_unlock_single(so, SOLOCKED);
1786 1797 mutex_exit(&so->so_lock);
1787 1798
1788 1799 return (0);
1789 1800
1790 1801 err:
1791 1802 SOCKPARAMS_DEC_REF(sp);
1792 1803 setf(nfd, NULL);
1793 1804 eprintsoline(so, error);
1794 1805 return (error);
1795 1806
1796 1807 peelerr:
1797 1808 mutex_exit(&nso->so_lock);
1798 1809 mutex_enter(&so->so_lock);
1799 1810 ASSERT(nso->so_count == 1);
1800 1811 nso->so_count = 0;
1801 1812 so_unlock_single(so, SOLOCKED);
1802 1813 SSA_REFRELE(ss, ssa);
1803 1814 mutex_exit(&so->so_lock);
1804 1815
1805 1816 setf(nfd, NULL);
1806 1817 ASSERT(nvp->v_count == 1);
1807 1818 socket_destroy(nso);
1808 1819 eprintsoline(so, error);
1809 1820 return (error);
1810 1821 }
1811 1822 default:
1812 1823 return (EINVAL);
1813 1824 }
1814 1825 }
1815 1826
1816 1827 /*ARGSUSED*/
1817 1828 static int
1818 1829 sosctp_close(struct sonode *so, int flag, struct cred *cr)
1819 1830 {
1820 1831 struct sctp_sonode *ss;
1821 1832 struct sctp_sa_id *ssi;
1822 1833 struct sctp_soassoc *ssa;
1823 1834 int32_t i;
1824 1835
1825 1836 ss = SOTOSSO(so);
1826 1837
1827 1838 /*
1828 1839 * Initiate connection shutdown. Tell SCTP if there is any data
1829 1840 * left unread.
1830 1841 */
1831 1842 sctp_recvd((struct sctp_s *)so->so_proto_handle,
1832 1843 so->so_rcvbuf - so->so_rcv_queued);
1833 1844 (void) sctp_disconnect((struct sctp_s *)so->so_proto_handle);
1834 1845
1835 1846 /*
1836 1847 * New associations can't come in, but old ones might get
1837 1848 * closed in upcall. Protect against that by taking a reference
1838 1849 * on the association.
1839 1850 */
1840 1851 mutex_enter(&so->so_lock);
1841 1852 ssi = ss->ss_assocs;
1842 1853 for (i = 0; i < ss->ss_maxassoc; i++, ssi++) {
1843 1854 if ((ssa = ssi->ssi_assoc) != NULL) {
1844 1855 SSA_REFHOLD(ssa);
1845 1856 sosctp_assoc_isdisconnected(ssa, 0);
1846 1857 mutex_exit(&so->so_lock);
1847 1858
1848 1859 sctp_recvd(ssa->ssa_conn, so->so_rcvbuf -
1849 1860 ssa->ssa_rcv_queued);
1850 1861 (void) sctp_disconnect(ssa->ssa_conn);
1851 1862
1852 1863 mutex_enter(&so->so_lock);
1853 1864 SSA_REFRELE(ss, ssa);
1854 1865 }
1855 1866 }
1856 1867 mutex_exit(&so->so_lock);
1857 1868
1858 1869 return (0);
1859 1870 }
1860 1871
1861 1872 /*
1862 1873 * Closes incoming connections which were never accepted, frees
1863 1874 * resources.
1864 1875 */
1865 1876 /* ARGSUSED */
1866 1877 void
1867 1878 sosctp_fini(struct sonode *so, struct cred *cr)
1868 1879 {
1869 1880 struct sctp_sonode *ss;
1870 1881 struct sctp_sa_id *ssi;
1871 1882 struct sctp_soassoc *ssa;
1872 1883 int32_t i;
1873 1884
1874 1885 ss = SOTOSSO(so);
1875 1886
1876 1887 ASSERT(so->so_ops == &sosctp_sonodeops ||
1877 1888 so->so_ops == &sosctp_seq_sonodeops);
1878 1889
1879 1890 /* We are the sole owner of so now */
1880 1891 mutex_enter(&so->so_lock);
1881 1892
1882 1893 /* Free all pending connections */
1883 1894 so_acceptq_flush(so, B_TRUE);
1884 1895
1885 1896 ssi = ss->ss_assocs;
1886 1897 for (i = 0; i < ss->ss_maxassoc; i++, ssi++) {
1887 1898 if ((ssa = ssi->ssi_assoc) != NULL) {
1888 1899 SSA_REFHOLD(ssa);
1889 1900 mutex_exit(&so->so_lock);
1890 1901
1891 1902 sctp_close((struct sctp_s *)ssa->ssa_conn);
1892 1903
1893 1904 mutex_enter(&so->so_lock);
1894 1905 ssa->ssa_conn = NULL;
1895 1906 sosctp_assoc_free(ss, ssa);
1896 1907 }
1897 1908 }
1898 1909 if (ss->ss_assocs != NULL) {
1899 1910 ASSERT(ss->ss_assoccnt == 0);
1900 1911 kmem_free(ss->ss_assocs,
1901 1912 ss->ss_maxassoc * sizeof (struct sctp_sa_id));
1902 1913 }
1903 1914 mutex_exit(&so->so_lock);
1904 1915
1905 1916 if (so->so_proto_handle)
1906 1917 sctp_close((struct sctp_s *)so->so_proto_handle);
1907 1918 so->so_proto_handle = NULL;
1908 1919
1909 1920 /*
1910 1921 * Note until sctp_close() is called, SCTP can still send up
1911 1922 * messages, such as event notifications. So we should flush
1912 1923 * the recevie buffer after calling sctp_close().
1913 1924 */
1914 1925 mutex_enter(&so->so_lock);
1915 1926 so_rcv_flush(so);
1916 1927 mutex_exit(&so->so_lock);
1917 1928
1918 1929 sonode_fini(so);
1919 1930 }
1920 1931
1921 1932 /*
1922 1933 * Upcalls from SCTP
1923 1934 */
1924 1935
1925 1936 /*
1926 1937 * This is the upcall function for 1-N (SOCK_SEQPACKET) socket when a new
1927 1938 * association is created. Note that the first argument (handle) is of type
1928 1939 * sctp_sonode *, which is the one changed to a listener for new
1929 1940 * associations. All the other upcalls for 1-N socket take sctp_soassoc *
1930 1941 * as handle. The only exception is the su_properties upcall, which
1931 1942 * can take both types as handle.
1932 1943 */
1933 1944 /* ARGSUSED */
1934 1945 sock_upper_handle_t
1935 1946 sctp_assoc_newconn(sock_upper_handle_t parenthandle,
1936 1947 sock_lower_handle_t connind, sock_downcalls_t *dc,
1937 1948 struct cred *peer_cred, pid_t peer_cpid, sock_upcalls_t **ucp)
1938 1949 {
1939 1950 struct sctp_sonode *lss = (struct sctp_sonode *)parenthandle;
1940 1951 struct sonode *lso = &lss->ss_so;
1941 1952 struct sctp_soassoc *ssa;
1942 1953 sctp_assoc_t id;
1943 1954
1944 1955 ASSERT(lss->ss_type == SOSCTP_SOCKET);
1945 1956 ASSERT(lso->so_state & SS_ACCEPTCONN);
1946 1957 ASSERT(lso->so_proto_handle != NULL); /* closed conn */
1947 1958 ASSERT(lso->so_type == SOCK_SEQPACKET);
1948 1959
1949 1960 mutex_enter(&lso->so_lock);
1950 1961
1951 1962 if ((id = sosctp_aid_get(lss)) == -1) {
1952 1963 /*
1953 1964 * Array not large enough; increase size.
1954 1965 */
1955 1966 if (sosctp_aid_grow(lss, lss->ss_maxassoc, KM_NOSLEEP) < 0) {
1956 1967 mutex_exit(&lso->so_lock);
1957 1968 return (NULL);
1958 1969 }
1959 1970 id = sosctp_aid_get(lss);
1960 1971 ASSERT(id != -1);
1961 1972 }
1962 1973
1963 1974 /*
1964 1975 * Create soassoc for this connection
1965 1976 */
1966 1977 ssa = sosctp_assoc_create(lss, KM_NOSLEEP);
1967 1978 if (ssa == NULL) {
1968 1979 mutex_exit(&lso->so_lock);
1969 1980 return (NULL);
1970 1981 }
1971 1982 sosctp_aid_reserve(lss, id, 1);
1972 1983 lss->ss_assocs[id].ssi_assoc = ssa;
1973 1984 ++lss->ss_assoccnt;
1974 1985 ssa->ssa_id = id;
1975 1986 ssa->ssa_conn = (struct sctp_s *)connind;
1976 1987 ssa->ssa_state = (SS_ISBOUND | SS_ISCONNECTED);
1977 1988 ssa->ssa_wroff = lss->ss_wroff;
1978 1989 ssa->ssa_wrsize = lss->ss_wrsize;
1979 1990
1980 1991 mutex_exit(&lso->so_lock);
1981 1992
1982 1993 *ucp = &sosctp_assoc_upcalls;
1983 1994
1984 1995 return ((sock_upper_handle_t)ssa);
1985 1996 }
1986 1997
1987 1998 /* ARGSUSED */
1988 1999 static void
1989 2000 sctp_assoc_connected(sock_upper_handle_t handle, sock_connid_t id,
1990 2001 struct cred *peer_cred, pid_t peer_cpid)
1991 2002 {
1992 2003 struct sctp_soassoc *ssa = (struct sctp_soassoc *)handle;
1993 2004 struct sonode *so = &ssa->ssa_sonode->ss_so;
1994 2005
1995 2006 ASSERT(so->so_type == SOCK_SEQPACKET);
1996 2007 ASSERT(ssa->ssa_conn);
1997 2008
1998 2009 mutex_enter(&so->so_lock);
1999 2010 sosctp_assoc_isconnected(ssa);
2000 2011 mutex_exit(&so->so_lock);
2001 2012 }
2002 2013
2003 2014 /* ARGSUSED */
2004 2015 static int
2005 2016 sctp_assoc_disconnected(sock_upper_handle_t handle, sock_connid_t id, int error)
2006 2017 {
2007 2018 struct sctp_soassoc *ssa = (struct sctp_soassoc *)handle;
2008 2019 struct sonode *so = &ssa->ssa_sonode->ss_so;
2009 2020 int ret;
2010 2021
2011 2022 ASSERT(so->so_type == SOCK_SEQPACKET);
2012 2023 ASSERT(ssa->ssa_conn != NULL);
2013 2024
2014 2025 mutex_enter(&so->so_lock);
2015 2026 sosctp_assoc_isdisconnected(ssa, error);
2016 2027 if (ssa->ssa_refcnt == 1) {
2017 2028 ret = 1;
2018 2029 ssa->ssa_conn = NULL;
2019 2030 } else {
2020 2031 ret = 0;
2021 2032 }
2022 2033 SSA_REFRELE(SOTOSSO(so), ssa);
2023 2034
2024 2035 cv_broadcast(&so->so_snd_cv);
2025 2036
2026 2037 mutex_exit(&so->so_lock);
2027 2038
2028 2039 return (ret);
2029 2040 }
2030 2041
2031 2042 /* ARGSUSED */
2032 2043 static void
2033 2044 sctp_assoc_disconnecting(sock_upper_handle_t handle, sock_opctl_action_t action,
2034 2045 uintptr_t arg)
2035 2046 {
2036 2047 struct sctp_soassoc *ssa = (struct sctp_soassoc *)handle;
2037 2048 struct sonode *so = &ssa->ssa_sonode->ss_so;
2038 2049
2039 2050 ASSERT(so->so_type == SOCK_SEQPACKET);
2040 2051 ASSERT(ssa->ssa_conn != NULL);
2041 2052 ASSERT(action == SOCK_OPCTL_SHUT_SEND);
2042 2053
2043 2054 mutex_enter(&so->so_lock);
2044 2055 sosctp_assoc_isdisconnecting(ssa);
2045 2056 mutex_exit(&so->so_lock);
2046 2057 }
2047 2058
2048 2059 /* ARGSUSED */
2049 2060 static ssize_t
2050 2061 sctp_assoc_recv(sock_upper_handle_t handle, mblk_t *mp, size_t len, int flags,
2051 2062 int *errorp, boolean_t *forcepush)
2052 2063 {
2053 2064 struct sctp_soassoc *ssa = (struct sctp_soassoc *)handle;
2054 2065 struct sctp_sonode *ss = ssa->ssa_sonode;
2055 2066 struct sonode *so = &ss->ss_so;
2056 2067 struct T_unitdata_ind *tind;
2057 2068 mblk_t *mp2;
2058 2069 union sctp_notification *sn;
2059 2070 struct sctp_sndrcvinfo *sinfo;
2060 2071 ssize_t space_available;
2061 2072
2062 2073 ASSERT(ssa->ssa_type == SOSCTP_ASSOC);
2063 2074 ASSERT(so->so_type == SOCK_SEQPACKET);
2064 2075 ASSERT(ssa->ssa_conn != NULL); /* closed conn */
2065 2076 ASSERT(mp != NULL);
2066 2077
2067 2078 ASSERT(errorp != NULL);
2068 2079 *errorp = 0;
2069 2080
2070 2081 /*
2071 2082 * Should be getting T_unitdata_req's only.
2072 2083 * Must have address as part of packet.
2073 2084 */
2074 2085 tind = (struct T_unitdata_ind *)mp->b_rptr;
2075 2086 ASSERT((DB_TYPE(mp) == M_PROTO) &&
2076 2087 (tind->PRIM_type == T_UNITDATA_IND));
2077 2088 ASSERT(tind->SRC_length);
2078 2089
2079 2090 mutex_enter(&so->so_lock);
2080 2091
2081 2092 /*
2082 2093 * For notify messages, need to fill in association id.
2083 2094 * For data messages, sndrcvinfo could be in ancillary data.
2084 2095 */
2085 2096 if (mp->b_flag & SCTP_NOTIFICATION) {
2086 2097 mp2 = mp->b_cont;
2087 2098 sn = (union sctp_notification *)mp2->b_rptr;
2088 2099 switch (sn->sn_header.sn_type) {
2089 2100 case SCTP_ASSOC_CHANGE:
2090 2101 sn->sn_assoc_change.sac_assoc_id = ssa->ssa_id;
2091 2102 break;
2092 2103 case SCTP_PEER_ADDR_CHANGE:
2093 2104 sn->sn_paddr_change.spc_assoc_id = ssa->ssa_id;
2094 2105 break;
2095 2106 case SCTP_REMOTE_ERROR:
2096 2107 sn->sn_remote_error.sre_assoc_id = ssa->ssa_id;
2097 2108 break;
2098 2109 case SCTP_SEND_FAILED:
2099 2110 sn->sn_send_failed.ssf_assoc_id = ssa->ssa_id;
2100 2111 break;
2101 2112 case SCTP_SHUTDOWN_EVENT:
2102 2113 sn->sn_shutdown_event.sse_assoc_id = ssa->ssa_id;
2103 2114 break;
2104 2115 case SCTP_ADAPTATION_INDICATION:
2105 2116 sn->sn_adaptation_event.sai_assoc_id = ssa->ssa_id;
2106 2117 break;
2107 2118 case SCTP_PARTIAL_DELIVERY_EVENT:
2108 2119 sn->sn_pdapi_event.pdapi_assoc_id = ssa->ssa_id;
2109 2120 break;
2110 2121 default:
2111 2122 ASSERT(0);
2112 2123 break;
2113 2124 }
2114 2125 } else {
2115 2126 if (tind->OPT_length > 0) {
2116 2127 struct cmsghdr *cmsg;
2117 2128 char *cend;
2118 2129
2119 2130 cmsg = (struct cmsghdr *)
2120 2131 ((uchar_t *)mp->b_rptr + tind->OPT_offset);
2121 2132 cend = (char *)cmsg + tind->OPT_length;
2122 2133 for (;;) {
2123 2134 if ((char *)(cmsg + 1) > cend ||
2124 2135 ((char *)cmsg + cmsg->cmsg_len) > cend) {
2125 2136 break;
2126 2137 }
2127 2138 if ((cmsg->cmsg_level == IPPROTO_SCTP) &&
2128 2139 (cmsg->cmsg_type == SCTP_SNDRCV)) {
2129 2140 sinfo = (struct sctp_sndrcvinfo *)
2130 2141 (cmsg + 1);
2131 2142 sinfo->sinfo_assoc_id = ssa->ssa_id;
2132 2143 break;
2133 2144 }
2134 2145 if (cmsg->cmsg_len > 0) {
2135 2146 cmsg = (struct cmsghdr *)
2136 2147 ((uchar_t *)cmsg + cmsg->cmsg_len);
2137 2148 } else {
2138 2149 break;
2139 2150 }
2140 2151 }
2141 2152 }
2142 2153 }
2143 2154
2144 2155 /*
2145 2156 * SCTP has reserved space in the header for storing a pointer.
2146 2157 * Put the pointer to assocation there, and queue the data.
2147 2158 */
2148 2159 SSA_REFHOLD(ssa);
2149 2160 ASSERT((mp->b_rptr - DB_BASE(mp)) >= sizeof (ssa));
2150 2161 *(struct sctp_soassoc **)DB_BASE(mp) = ssa;
2151 2162
2152 2163 ssa->ssa_rcv_queued += len;
2153 2164 space_available = so->so_rcvbuf - ssa->ssa_rcv_queued;
2154 2165 if (space_available <= 0)
2155 2166 ssa->ssa_flowctrld = B_TRUE;
2156 2167
2157 2168 so_enqueue_msg(so, mp, len);
2158 2169
2159 2170 /* so_notify_data drops so_lock */
2160 2171 so_notify_data(so, len);
2161 2172
2162 2173 return (space_available);
2163 2174 }
2164 2175
2165 2176 static void
2166 2177 sctp_assoc_xmitted(sock_upper_handle_t handle, boolean_t qfull)
2167 2178 {
2168 2179 struct sctp_soassoc *ssa = (struct sctp_soassoc *)handle;
2169 2180 struct sctp_sonode *ss = ssa->ssa_sonode;
2170 2181
2171 2182 ASSERT(ssa->ssa_type == SOSCTP_ASSOC);
2172 2183 ASSERT(ss->ss_so.so_type == SOCK_SEQPACKET);
2173 2184 ASSERT(ssa->ssa_conn != NULL);
2174 2185
2175 2186 mutex_enter(&ss->ss_so.so_lock);
2176 2187
2177 2188 ssa->ssa_snd_qfull = qfull;
2178 2189
2179 2190 /*
2180 2191 * Wake blocked writers.
2181 2192 */
2182 2193 cv_broadcast(&ss->ss_so.so_snd_cv);
2183 2194
2184 2195 mutex_exit(&ss->ss_so.so_lock);
2185 2196 }
2186 2197
2187 2198 static void
2188 2199 sctp_assoc_properties(sock_upper_handle_t handle,
2189 2200 struct sock_proto_props *soppp)
2190 2201 {
2191 2202 struct sctp_soassoc *ssa = (struct sctp_soassoc *)handle;
2192 2203 struct sonode *so;
2193 2204
2194 2205 if (ssa->ssa_type == SOSCTP_ASSOC) {
2195 2206 so = &ssa->ssa_sonode->ss_so;
2196 2207
2197 2208 mutex_enter(&so->so_lock);
2198 2209
2199 2210 /* Per assoc_id properties. */
2200 2211 if (soppp->sopp_flags & SOCKOPT_WROFF)
2201 2212 ssa->ssa_wroff = soppp->sopp_wroff;
2202 2213 if (soppp->sopp_flags & SOCKOPT_MAXBLK)
2203 2214 ssa->ssa_wrsize = soppp->sopp_maxblk;
2204 2215 } else {
2205 2216 so = &((struct sctp_sonode *)handle)->ss_so;
2206 2217 mutex_enter(&so->so_lock);
2207 2218
2208 2219 if (soppp->sopp_flags & SOCKOPT_WROFF)
2209 2220 so->so_proto_props.sopp_wroff = soppp->sopp_wroff;
2210 2221 if (soppp->sopp_flags & SOCKOPT_MAXBLK)
2211 2222 so->so_proto_props.sopp_maxblk = soppp->sopp_maxblk;
2212 2223 if (soppp->sopp_flags & SOCKOPT_RCVHIWAT) {
2213 2224 ssize_t lowat;
2214 2225
2215 2226 so->so_rcvbuf = soppp->sopp_rxhiwat;
2216 2227 /*
2217 2228 * The low water mark should be adjusted properly
2218 2229 * if the high water mark is changed. It should
2219 2230 * not be bigger than 1/4 of high water mark.
2220 2231 */
2221 2232 lowat = soppp->sopp_rxhiwat >> 2;
↓ open down ↓ |
436 lines elided |
↑ open up ↑ |
2222 2233 if (so->so_rcvlowat > lowat) {
2223 2234 /* Sanity check... */
2224 2235 if (lowat == 0)
2225 2236 so->so_rcvlowat = soppp->sopp_rxhiwat;
2226 2237 else
2227 2238 so->so_rcvlowat = lowat;
2228 2239 }
2229 2240 }
2230 2241 }
2231 2242 mutex_exit(&so->so_lock);
2243 +}
2244 +
2245 +static conn_pid_node_list_hdr_t *
2246 +sctp_get_sock_pid_list(sock_upper_handle_t handle)
2247 +{
2248 + struct sctp_soassoc *ssa = (struct sctp_soassoc *)handle;
2249 + struct sonode *so;
2250 +
2251 + if (ssa->ssa_type == SOSCTP_ASSOC)
2252 + so = &ssa->ssa_sonode->ss_so;
2253 + else
2254 + so = &((struct sctp_sonode *)handle)->ss_so;
2255 +
2256 + return (so_get_sock_pid_list((sock_upper_handle_t)so));
2232 2257 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX