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