1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2017 Joyent, Inc.
  25  */
  26 
  27 #include <sys/types.h>
  28 #include <sys/t_lock.h>
  29 #include <sys/param.h>
  30 #include <sys/systm.h>
  31 #include <sys/buf.h>
  32 #include <sys/vfs.h>
  33 #include <sys/vnode.h>
  34 #include <sys/debug.h>
  35 #include <sys/errno.h>
  36 #include <sys/stropts.h>
  37 #include <sys/cmn_err.h>
  38 #include <sys/sysmacros.h>
  39 #include <sys/policy.h>
  40 
  41 #include <sys/filio.h>
  42 #include <sys/sockio.h>
  43 
  44 #include <sys/project.h>
  45 #include <sys/tihdr.h>
  46 #include <sys/strsubr.h>
  47 
  48 #include <sys/socket.h>
  49 #include <sys/socketvar.h>
  50 #include <sys/strsun.h>
  51 
  52 #include <sys/tsol/label.h>
  53 
  54 #include <inet/sdp_itf.h>
  55 #include "socksdp.h"
  56 #include <fs/sockfs/sockcommon.h>
  57 
  58 /*
  59  * SDP sockfs sonode operations
  60  */
  61 static int sosdp_init(struct sonode *, struct sonode *, struct cred *, int);
  62 static int sosdp_accept(struct sonode *, int, struct cred *, struct sonode **);
  63 static int sosdp_bind(struct sonode *, struct sockaddr *, socklen_t, int,
  64     struct cred *);
  65 static int sosdp_listen(struct sonode *, int, struct cred *);
  66 static int sosdp_connect(struct sonode *, struct sockaddr *, socklen_t,
  67     int, int, struct cred *);
  68 static int sosdp_recvmsg(struct sonode *, struct nmsghdr *, struct uio *,
  69     struct cred *);
  70 static int sosdp_sendmsg(struct sonode *, struct nmsghdr *, struct uio *,
  71     struct cred *);
  72 static int sosdp_getpeername(struct sonode *, struct sockaddr *, socklen_t *,
  73     boolean_t, struct cred *);
  74 static int sosdp_getsockname(struct sonode *, struct sockaddr *, socklen_t *,
  75     struct cred *);
  76 static int sosdp_shutdown(struct sonode *, int, struct cred *);
  77 static int sosdp_getsockopt(struct sonode *, int, int, void *, socklen_t *,
  78     int, struct cred *);
  79 static int sosdp_setsockopt(struct sonode *, int, int, const void *,
  80     socklen_t, struct cred *);
  81 static int sosdp_ioctl(struct sonode *, int, intptr_t, int, struct cred *,
  82     int32_t *);
  83 static int sosdp_poll(struct sonode *, short, int, short *,
  84     struct pollhead **);
  85 static int sosdp_close(struct sonode *, int, struct cred *);
  86 void sosdp_fini(struct sonode *, struct cred *);
  87 
  88 
  89 /*
  90  * Socket upcalls
  91  */
  92 static void *sdp_sock_newconn(void *parenthandle, void *connind);
  93 static void sdp_sock_connected(void *handle);
  94 static void sdp_sock_disconnected(void *handle, int error);
  95 static void sdp_sock_connfail(void *handle, int error);
  96 static int sdp_sock_recv(void *handle, mblk_t *mp, int flags);
  97 static void sdp_sock_xmitted(void *handle, int txqueued);
  98 static void sdp_sock_urgdata(void *handle);
  99 static void sdp_sock_ordrel(void *handle);
 100 
 101 sonodeops_t sosdp_sonodeops = {
 102         sosdp_init,                     /* sop_init     */
 103         sosdp_accept,                   /* sop_accept   */
 104         sosdp_bind,                     /* sop_bind     */
 105         sosdp_listen,                   /* sop_listen   */
 106         sosdp_connect,                  /* sop_connect  */
 107         sosdp_recvmsg,                  /* sop_recvmsg  */
 108         sosdp_sendmsg,                  /* sop_sendmsg  */
 109         so_sendmblk_notsupp,            /* sop_sendmblk */
 110         sosdp_getpeername,              /* sop_getpeername */
 111         sosdp_getsockname,              /* sop_getsockname */
 112         sosdp_shutdown,                 /* sop_shutdown */
 113         sosdp_getsockopt,               /* sop_getsockopt */
 114         sosdp_setsockopt,               /* sop_setsockopt */
 115         sosdp_ioctl,                    /* sop_ioctl    */
 116         sosdp_poll,                     /* sop_poll     */
 117         sosdp_close,                    /* sop_close    */
 118 };
 119 
 120 sdp_upcalls_t sosdp_sock_upcalls = {
 121         sdp_sock_newconn,
 122         sdp_sock_connected,
 123         sdp_sock_disconnected,
 124         sdp_sock_connfail,
 125         sdp_sock_recv,
 126         sdp_sock_xmitted,
 127         sdp_sock_urgdata,
 128         sdp_sock_ordrel,
 129 };
 130 
 131 /* ARGSUSED */
 132 static int
 133 sosdp_init(struct sonode *so, struct sonode *pso, struct cred *cr, int flags)
 134 {
 135         int error = 0;
 136         sdp_sockbuf_limits_t sbl;
 137         sdp_upcalls_t *upcalls;
 138 
 139         if (pso != NULL) {
 140                 /* passive open, just inherit settings from parent */
 141 
 142                 mutex_enter(&so->so_lock);
 143 
 144                 so->so_state |= (SS_ISBOUND | SS_ISCONNECTED |
 145                     (pso->so_state & SS_ASYNC));
 146                 sosdp_so_inherit(pso, so);
 147                 so->so_proto_props = pso->so_proto_props;
 148 
 149                 mutex_exit(&so->so_lock);
 150 
 151                 return (0);
 152         }
 153 
 154         if ((error = secpolicy_basic_net_access(cr)) != 0)
 155                 return (error);
 156 
 157         upcalls = &sosdp_sock_upcalls;
 158 
 159         so->so_proto_handle = (sock_lower_handle_t)sdp_create(so, NULL,
 160             so->so_family, SDP_CAN_BLOCK, upcalls, &sbl, cr, &error);
 161         if (so->so_proto_handle == NULL)
 162                 return (ENOMEM);
 163 
 164         so->so_rcvbuf = sbl.sbl_rxbuf;
 165         so->so_rcvlowat = sbl.sbl_rxlowat;
 166         so->so_sndbuf = sbl.sbl_txbuf;
 167         so->so_sndlowat = sbl.sbl_txlowat;
 168 
 169         return (error);
 170 }
 171 
 172 /*
 173  * Accept incoming connection.
 174  */
 175 /* ARGSUSED */
 176 static int
 177 sosdp_accept(struct sonode *lso, int fflag, struct cred *cr,
 178     struct sonode **nsop)
 179 {
 180         int error = 0;
 181         struct sonode *nso;
 182 
 183         dprint(3, ("sosdp_accept: so:%p so_proto_handle:%p", (void *)lso,
 184             (void *)lso->so_proto_handle));
 185 
 186         if (!(lso->so_state & SS_ACCEPTCONN)) {
 187                 /*
 188                  * Not a listen socket.
 189                  */
 190                 eprintsoline(lso, EINVAL);
 191                 return (EINVAL);
 192         }
 193         /*
 194          * Returns right away if socket is nonblocking.
 195          */
 196         error = so_acceptq_dequeue(lso, (fflag & (FNONBLOCK|FNDELAY)), &nso);
 197         if (error != 0) {
 198                 eprintsoline(lso, error);
 199                 dprint(4, ("sosdp_accept: failed %d:lso:%p so_proto_handle:%p",
 200                     error, (void *)lso, (void *)lso->so_proto_handle));
 201                 return (error);
 202         }
 203 
 204         dprint(2, ("sosdp_accept: new %p\n", (void *)nso));
 205         *nsop = nso;
 206 
 207         return (0);
 208 }
 209 
 210 /*
 211  * Bind local endpoint.
 212  */
 213 /* ARGSUSED */
 214 int
 215 sosdp_bind(struct sonode *so, struct sockaddr *name, socklen_t namelen,
 216     int flags, struct cred *cr)
 217 {
 218         int     error = 0;
 219 
 220         if (!(flags & _SOBIND_LOCK_HELD)) {
 221                 mutex_enter(&so->so_lock);
 222                 so_lock_single(so);     /* Set SOLOCKED */
 223         } else {
 224                 ASSERT(MUTEX_HELD(&so->so_lock));
 225                 ASSERT(so->so_flag & SOLOCKED);
 226         }
 227 
 228         if ((so->so_state & SS_ISBOUND) || name == NULL || namelen == 0) {
 229                 /*
 230                  * Multiple binds not allowed for any SDP socket.
 231                  * Also binding with null address is not supported.
 232                  */
 233                 error = EINVAL;
 234                 eprintsoline(so, error);
 235                 goto done;
 236         }
 237 
 238         /*
 239          * X/Open requires this check
 240          */
 241         if (so->so_state & SS_CANTSENDMORE) {
 242                 error = EINVAL;
 243                 goto done;
 244         }
 245 
 246         /*
 247          * Protocol module does address family checks
 248          */
 249         mutex_exit(&so->so_lock);
 250 
 251         error = sdp_bind((struct sdp_conn_struct_t *)so->so_proto_handle,
 252             name, namelen);
 253 
 254         mutex_enter(&so->so_lock);
 255 
 256         if (error == 0) {
 257                 so->so_state |= SS_ISBOUND;
 258         } else {
 259                 eprintsoline(so, error);
 260         }
 261 done:
 262         if (!(flags & _SOBIND_LOCK_HELD)) {
 263                 so_unlock_single(so, SOLOCKED);
 264                 mutex_exit(&so->so_lock);
 265         } else {
 266                 /* If the caller held the lock don't release it here */
 267                 ASSERT(MUTEX_HELD(&so->so_lock));
 268                 ASSERT(so->so_flag & SOLOCKED);
 269         }
 270         return (error);
 271 }
 272 
 273 /*
 274  * Turn socket into a listen socket.
 275  */
 276 /* ARGSUSED */
 277 static int
 278 sosdp_listen(struct sonode *so, int backlog, struct cred *cr)
 279 {
 280         int error = 0;
 281 
 282         mutex_enter(&so->so_lock);
 283         so_lock_single(so);
 284 
 285         /*
 286          * If this socket is trying to do connect, or if it has
 287          * been connected, disallow.
 288          */
 289         if (so->so_state & (SS_ISCONNECTING | SS_ISCONNECTED |
 290             SS_ISDISCONNECTING | SS_CANTRCVMORE | SS_CANTSENDMORE)) {
 291                 error = EINVAL;
 292                 eprintsoline(so, EINVAL);
 293                 goto done;
 294         }
 295         /*
 296          * If listen() is only called to change backlog, we don't
 297          * need to notify protocol module.
 298          */
 299         if (so->so_state & SS_ACCEPTCONN) {
 300                 so->so_backlog = backlog;
 301                 goto done;
 302         }
 303 
 304         mutex_exit(&so->so_lock);
 305 
 306         error = sdp_listen((struct sdp_conn_struct_t *)so->so_proto_handle,
 307             backlog);
 308 
 309         mutex_enter(&so->so_lock);
 310         if (error == 0) {
 311                 so->so_state |= (SS_ACCEPTCONN | SS_ISBOUND);
 312                 so->so_backlog = backlog;
 313         } else {
 314                 eprintsoline(so, error);
 315         }
 316 done:
 317         so_unlock_single(so, SOLOCKED);
 318         mutex_exit(&so->so_lock);
 319 
 320         return (error);
 321 }
 322 
 323 /*
 324  * Active open.
 325  */
 326 /*ARGSUSED*/
 327 static int
 328 sosdp_connect(struct sonode *so, struct sockaddr *name,
 329     socklen_t namelen, int fflag, int flags, struct cred *cr)
 330 {
 331         int error = 0;
 332 
 333         mutex_enter(&so->so_lock);
 334         so_lock_single(so);
 335 
 336         /*
 337          * Can't connect() after listen(), or if the socket is already
 338          * connected.
 339          */
 340         if (so->so_state & (SS_ACCEPTCONN|SS_ISCONNECTED|SS_ISCONNECTING)) {
 341                 if (so->so_state & SS_ISCONNECTED) {
 342                         error = EISCONN;
 343                 } else if (so->so_state & SS_ISCONNECTING) {
 344                         error = EALREADY;
 345                 } else {
 346                         error = EOPNOTSUPP;
 347                 }
 348                 eprintsoline(so, error);
 349                 goto done;
 350         }
 351 
 352         /*
 353          * check for failure of an earlier call
 354          */
 355         if (so->so_error != 0) {
 356                 error = sogeterr(so, B_TRUE);
 357                 eprintsoline(so, error);
 358                 goto done;
 359         }
 360 
 361         /*
 362          * Connection is closing, or closed, don't allow reconnect.
 363          * TCP allows this to proceed, but the socket remains unwriteable.
 364          * BSD returns EINVAL.
 365          */
 366         if (so->so_state & (SS_ISDISCONNECTING|SS_CANTRCVMORE|
 367             SS_CANTSENDMORE)) {
 368                 error = EINVAL;
 369                 eprintsoline(so, error);
 370                 goto done;
 371         }
 372         if (name == NULL || namelen == 0) {
 373                 eprintsoline(so, EINVAL);
 374                 goto done;
 375         }
 376         soisconnecting(so);
 377         mutex_exit(&so->so_lock);
 378 
 379         error = sdp_connect((struct sdp_conn_struct_t *)so->so_proto_handle,
 380             name, namelen);
 381 
 382         mutex_enter(&so->so_lock);
 383         if (error == 0) {
 384                 /*
 385                  * Allow other threads to access the socket
 386                  */
 387                 error = sowaitconnected(so, fflag, 0);
 388                 dprint(4,
 389                     ("sosdp_connect: wait on so:%p "
 390                     "so_proto_handle:%p failed:%d",
 391                     (void *)so, (void *)so->so_proto_handle, error));
 392         }
 393 
 394         switch (error) {
 395         case 0:
 396         case EINPROGRESS:
 397         case EALREADY:
 398         case EINTR:
 399                 /* Non-fatal errors */
 400                 so->so_state |= SS_ISBOUND;
 401                 break;
 402         default:
 403                 /* clear SS_ISCONNECTING in case it was set */
 404                 so->so_state &= ~SS_ISCONNECTING;
 405                 break;
 406         }
 407 done:
 408         so_unlock_single(so, SOLOCKED);
 409         mutex_exit(&so->so_lock);
 410         return (error);
 411 }
 412 
 413 /*
 414  * Receive data.
 415  */
 416 /* ARGSUSED */
 417 int
 418 sosdp_recvmsg(struct sonode *so, struct nmsghdr *msg, struct uio *uiop,
 419     struct cred *cr)
 420 {
 421         int flags, error = 0;
 422         int size;
 423 
 424         flags = msg->msg_flags;
 425         msg->msg_flags = 0;
 426 
 427 
 428         if (!(so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING|
 429             SS_CANTRCVMORE))) {
 430                 return (ENOTCONN);
 431         }
 432 
 433         /*
 434          * flag possibilities:
 435          *
 436          * MSG_PEEK     Don't consume data
 437          * MSG_WAITALL  Wait for full quantity of data (ignored if MSG_PEEK)
 438          * MSG_DONTWAIT Non-blocking (same as FNDELAY | FNONBLOCK)
 439          *
 440          * MSG_WAITALL can return less than the full buffer if either
 441          *
 442          * 1. we would block and we are non-blocking
 443          * 2. a full message cannot be delivered
 444          *
 445          */
 446 
 447         mutex_enter(&so->so_lock);
 448 
 449         /*
 450          * Allow just one reader at a time.
 451          */
 452         error = so_lock_read_intr(so,
 453             uiop->uio_fmode | ((flags & MSG_DONTWAIT) ? FNONBLOCK : 0));
 454         if (error != 0) {
 455                 mutex_exit(&so->so_lock);
 456                 return (error);
 457         }
 458         size = uiop->uio_resid;
 459         mutex_exit(&so->so_lock);
 460 
 461         if (!(so->so_state & SS_CANTRCVMORE)) {
 462                 if (uiop->uio_fmode & (FNDELAY|FNONBLOCK)) {
 463                         flags |= MSG_DONTWAIT;
 464                 }
 465                 error = sdp_recv(
 466                     (struct sdp_conn_struct_t *)so->so_proto_handle, msg,
 467                     size, flags, uiop);
 468         } else {
 469                 msg->msg_controllen = 0;
 470                 msg->msg_namelen = 0;
 471         }
 472 done:
 473         mutex_enter(&so->so_lock);
 474         so_unlock_read(so);
 475         mutex_exit(&so->so_lock);
 476         return (error);
 477 }
 478 
 479 /*
 480  * Send message.
 481  */
 482 /* ARGSUSED */
 483 static int
 484 sosdp_sendmsg(struct sonode *so, struct nmsghdr *msg, struct uio *uiop,
 485     struct cred *cr)
 486 {
 487         int flags;
 488         ssize_t count;
 489         int error;
 490 
 491         ASSERT(so->so_type == SOCK_STREAM);
 492 
 493         dprint(4, ("sosdp_sendmsg: so:%p so_proto_handle:%p",
 494             (void *)so, (void *)so->so_proto_handle));
 495 
 496         flags = msg->msg_flags;
 497 
 498         if (msg->msg_controllen != 0) {
 499                 return (EOPNOTSUPP);
 500         }
 501 
 502         mutex_enter(&so->so_lock);
 503         if (so->so_state & SS_CANTSENDMORE) {
 504                 mutex_exit(&so->so_lock);
 505                 return (EPIPE);
 506         }
 507 
 508         if (so->so_error != 0) {
 509                 error = sogeterr(so, B_TRUE);
 510                 mutex_exit(&so->so_lock);
 511                 return (error);
 512         }
 513 
 514         if (uiop->uio_fmode & (FNDELAY|FNONBLOCK))
 515                 flags |= MSG_DONTWAIT;
 516 
 517         count = uiop->uio_resid;
 518 
 519         if (!(so->so_state & (SS_ISCONNECTING | SS_ISCONNECTED))) {
 520                 dprint(4, ("sosdp_sendmsg: invalid state: <%x>",
 521                     so->so_state));
 522                 mutex_exit(&so->so_lock);
 523                 return (ENOTCONN);
 524         }
 525 
 526         mutex_exit(&so->so_lock);
 527         error = sdp_send((struct sdp_conn_struct_t *)so->so_proto_handle,
 528             msg, count, flags, uiop);
 529 
 530         return (error);
 531 }
 532 
 533 /*
 534  * Get address of remote node.
 535  */
 536 /* ARGSUSED */
 537 static int
 538 sosdp_getpeername(struct sonode *so, struct sockaddr *addr, socklen_t *addrlen,
 539     boolean_t accept, struct cred *cr)
 540 {
 541 
 542         if (!accept && !(so->so_state & SS_ISCONNECTED)) {
 543                 return (ENOTCONN);
 544         } else {
 545                 return (sdp_getpeername(
 546                     (struct sdp_conn_struct_t *)so->so_proto_handle,
 547                     addr, addrlen));
 548         }
 549 }
 550 
 551 /*
 552  * Get local address.
 553  */
 554 /* ARGSUSED */
 555 static int
 556 sosdp_getsockname(struct sonode *so, struct sockaddr *addr, socklen_t *addrlen,
 557     struct cred *cr)
 558 {
 559         mutex_enter(&so->so_lock);
 560 
 561         if (!(so->so_state & SS_ISBOUND)) {
 562                 /*
 563                  * Zero address, except for address family
 564                  */
 565                 if (so->so_family == AF_INET || so->so_family == AF_INET6) {
 566                         bzero(addr, *addrlen);
 567                         *addrlen = (so->so_family == AF_INET6) ?
 568                             sizeof (struct sockaddr_in6) :
 569                             sizeof (struct sockaddr_in);
 570                         addr->sa_family = so->so_family;
 571                 }
 572                 mutex_exit(&so->so_lock);
 573                 return (0);
 574         } else {
 575                 mutex_exit(&so->so_lock);
 576                 return (sdp_getsockname(
 577                     (struct sdp_conn_struct_t *)so->so_proto_handle,
 578                     addr, addrlen));
 579         }
 580 }
 581 
 582 /*
 583  * Called from shutdown().
 584  */
 585 /* ARGSUSED */
 586 static int
 587 sosdp_shutdown(struct sonode *so, int how, struct cred *cr)
 588 {
 589         uint_t state_change;
 590         int error = 0;
 591 
 592         mutex_enter(&so->so_lock);
 593         so_lock_single(so);
 594         /*
 595          * Record the current state and then perform any state changes.
 596          * Then use the difference between the old and new states to
 597          * determine which needs to be done.
 598          */
 599         state_change = so->so_state;
 600         if (!(state_change & SS_ISCONNECTED)) {
 601                 error = ENOTCONN;
 602                 goto done;
 603         }
 604 
 605         switch (how) {
 606         case SHUT_RD:
 607                 socantrcvmore(so);
 608                 break;
 609         case SHUT_WR:
 610                 socantsendmore(so);
 611                 break;
 612         case SHUT_RDWR:
 613                 socantsendmore(so);
 614                 socantrcvmore(so);
 615                 break;
 616         default:
 617                 error = EINVAL;
 618                 goto done;
 619         }
 620 
 621         state_change = so->so_state & ~state_change;
 622 
 623         if (state_change & SS_CANTSENDMORE) {
 624                 so->so_state |= SS_ISDISCONNECTING;
 625         }
 626         so_notify_shutdown(so);
 627 
 628         if (state_change & SS_CANTSENDMORE) {
 629                 error = sdp_shutdown(
 630                     (struct sdp_conn_struct_t *)so->so_proto_handle, how);
 631         }
 632 
 633         mutex_enter(&so->so_lock);
 634 done:
 635         so_unlock_single(so, SOLOCKED);
 636         mutex_exit(&so->so_lock);
 637 
 638         /*
 639          * HACK: sdp_disconnect() may return EWOULDBLOCK.  But this error is
 640          * not documented in standard socket API.  Catch it here.
 641          */
 642         if (error == EWOULDBLOCK)
 643                 error = 0;
 644         return (error);
 645 }
 646 
 647 /*
 648  * Get socket options.
 649  */
 650 /*ARGSUSED*/
 651 static int
 652 sosdp_getsockopt(struct sonode *so, int level, int option_name,
 653     void *optval, socklen_t *optlenp, int flags, struct cred *cr)
 654 {
 655         int error = 0;
 656         void *option = NULL;
 657         socklen_t maxlen = *optlenp, len, optlen;
 658         uint32_t value;
 659         uint8_t buffer[4];
 660         void *optbuf = &buffer;
 661 
 662 
 663         mutex_enter(&so->so_lock);
 664 
 665         if (level == SOL_SOCKET) {
 666                 switch (option_name) {
 667                 case SO_TYPE:
 668                 case SO_ERROR:
 669                 case SO_DEBUG:
 670                 case SO_ACCEPTCONN:
 671                 case SO_REUSEADDR:
 672                 case SO_KEEPALIVE:
 673                 case SO_DONTROUTE:
 674                 case SO_BROADCAST:
 675                 case SO_USELOOPBACK:
 676                 case SO_OOBINLINE:
 677                 case SO_SNDBUF:
 678                 case SO_RCVBUF:
 679                 case SO_SNDLOWAT:
 680                 case SO_RCVLOWAT:
 681                 case SO_DGRAM_ERRIND:
 682                         if (maxlen < (t_uscalar_t)sizeof (int32_t)) {
 683                                 error = EINVAL;
 684                                 eprintsoline(so, error);
 685                                 goto done;
 686                         }
 687                         break;
 688                 case SO_LINGER:
 689                         if (maxlen < (t_uscalar_t)sizeof (struct linger)) {
 690                                 error = EINVAL;
 691                                 eprintsoline(so, error);
 692                                 goto done;
 693                         }
 694                         break;
 695                 }
 696                 len = (t_uscalar_t)sizeof (uint32_t);   /* Default */
 697                 option = &value;
 698 
 699                 switch (option_name) {
 700                 case SO_TYPE:
 701                         value = so->so_type;
 702                         goto copyout;
 703 
 704                 case SO_ERROR:
 705                         value = sogeterr(so, B_TRUE);
 706                         goto copyout;
 707 
 708                 case SO_ACCEPTCONN:
 709                         value = (so->so_state & SS_ACCEPTCONN) ?
 710                             SO_ACCEPTCONN : 0;
 711                         goto copyout;
 712 
 713                 case SO_DEBUG:
 714                 case SO_REUSEADDR:
 715                 case SO_KEEPALIVE:
 716                 case SO_DONTROUTE:
 717                 case SO_BROADCAST:
 718                 case SO_USELOOPBACK:
 719                 case SO_OOBINLINE:
 720                 case SO_DGRAM_ERRIND:
 721                         value = (so->so_options & option_name);
 722                         goto copyout;
 723 
 724                         /*
 725                          * The following options are only returned by sockfs
 726                          * when sdp_get_opt() fails.
 727                          */
 728 
 729                 case SO_LINGER:
 730                         option = &so->so_linger;
 731                         len = (t_uscalar_t)sizeof (struct linger);
 732                         break;
 733                 case SO_SNDBUF:
 734                         value = so->so_sndbuf;
 735                         len = (t_uscalar_t)sizeof (int);
 736                         goto copyout;
 737 
 738                 case SO_RCVBUF:
 739                         value = so->so_rcvbuf;
 740                         len = (t_uscalar_t)sizeof (int);
 741                         goto copyout;
 742 
 743                 case SO_SNDLOWAT:
 744                         value = so->so_sndlowat;
 745                         len = (t_uscalar_t)sizeof (int);
 746                         goto copyout;
 747 
 748                 case SO_RCVLOWAT:
 749                         value = so->so_rcvlowat;
 750                         len = (t_uscalar_t)sizeof (int);
 751                         goto copyout;
 752 
 753                 default:
 754                         option = NULL;
 755                         break;
 756                 }
 757         }
 758         if (maxlen > sizeof (buffer)) {
 759                 optbuf = kmem_alloc(maxlen, KM_SLEEP);
 760         }
 761         optlen = maxlen;
 762         mutex_exit(&so->so_lock);
 763         error = sdp_get_opt((struct sdp_conn_struct_t *)so->so_proto_handle,
 764             level, option_name, optbuf, &optlen);
 765         mutex_enter(&so->so_lock);
 766         ASSERT(optlen <= maxlen);
 767         if (error != 0) {
 768                 if (option == NULL) {
 769                         /* We have no fallback value */
 770                         eprintsoline(so, error);
 771                         goto free;
 772                 }
 773                 error = 0;
 774                 goto copyout;
 775         }
 776 
 777         option = optbuf;
 778         len = optlen;
 779 
 780 copyout:
 781         len = MIN(len, maxlen);
 782         bcopy(option, optval, len);
 783         *optlenp = len;
 784 
 785 free:
 786         if (optbuf != &buffer) {
 787                 kmem_free(optbuf, maxlen);
 788         }
 789 done:
 790         mutex_exit(&so->so_lock);
 791         return (error);
 792 }
 793 
 794 /*
 795  * Set socket options
 796  */
 797 /* ARGSUSED */
 798 static int
 799 sosdp_setsockopt(struct sonode *so, int level, int option_name,
 800     const void *optval, t_uscalar_t optlen, struct cred *cr)
 801 {
 802         void *conn = NULL;
 803         int error = 0;
 804 
 805         if (so->so_state & SS_CANTSENDMORE) {
 806                 return (EINVAL);
 807         }
 808 
 809         mutex_enter(&so->so_lock);
 810         so_lock_single(so);
 811 
 812         if (so->so_type == SOCK_STREAM) {
 813                 conn = (void *)so->so_proto_handle;
 814         }
 815 
 816         dprint(2, ("sosdp_setsockopt (%d) - conn %p %d %d \n",
 817             so->so_type, conn, level, option_name));
 818 
 819         if (conn != NULL) {
 820                 mutex_exit(&so->so_lock);
 821                 error = sdp_set_opt((struct sdp_conn_struct_t *)conn, level,
 822                     option_name, optval, optlen);
 823                 mutex_enter(&so->so_lock);
 824         }
 825 
 826         /*
 827          * Check for SOL_SOCKET options and record their values.
 828          * If we know about a SOL_SOCKET parameter and the transport
 829          * failed it with TBADOPT or TOUTSTATE (i.e. ENOPROTOOPT or
 830          * EPROTO) we let the setsockopt succeed.
 831          */
 832         if (level == SOL_SOCKET) {
 833                 boolean_t handled = B_FALSE;
 834 
 835                 /* Check parameters */
 836                 switch (option_name) {
 837                 case SO_DEBUG:
 838                 case SO_REUSEADDR:
 839                 case SO_KEEPALIVE:
 840                 case SO_DONTROUTE:
 841                 case SO_BROADCAST:
 842                 case SO_USELOOPBACK:
 843                 case SO_OOBINLINE:
 844                 case SO_SNDBUF:
 845                 case SO_RCVBUF:
 846                 case SO_SNDLOWAT:
 847                 case SO_RCVLOWAT:
 848                 case SO_DGRAM_ERRIND:
 849                         if (optlen != (t_uscalar_t)sizeof (int32_t)) {
 850                                 error = EINVAL;
 851                                 eprintsoline(so, error);
 852                                 goto done;
 853                         }
 854                         ASSERT(optval);
 855                         handled = B_TRUE;
 856                         break;
 857                 case SO_LINGER:
 858                         if (optlen != (t_uscalar_t)sizeof (struct linger)) {
 859                                 error = EINVAL;
 860                                 eprintsoline(so, error);
 861                                 goto done;
 862                         }
 863                         ASSERT(optval);
 864                         handled = B_TRUE;
 865                         break;
 866                 }
 867 
 868 #define intvalue (*(int32_t *)optval)
 869 
 870                 switch (option_name) {
 871                 case SO_TYPE:
 872                 case SO_ERROR:
 873                 case SO_ACCEPTCONN:
 874                         /* Can't be set */
 875                         error = ENOPROTOOPT;
 876                         goto done;
 877                 case SO_LINGER: {
 878                         struct linger *l = (struct linger *)optval;
 879 
 880                         so->so_linger.l_linger = l->l_linger;
 881                         if (l->l_onoff) {
 882                                 so->so_linger.l_onoff = SO_LINGER;
 883                                 so->so_options |= SO_LINGER;
 884                         } else {
 885                                 so->so_linger.l_onoff = 0;
 886                                 so->so_options &= ~SO_LINGER;
 887                         }
 888                         break;
 889                 }
 890 
 891                 case SO_DEBUG:
 892                 case SO_REUSEADDR:
 893                 case SO_KEEPALIVE:
 894                 case SO_DONTROUTE:
 895                 case SO_BROADCAST:
 896                 case SO_USELOOPBACK:
 897                 case SO_OOBINLINE:
 898                 case SO_DGRAM_ERRIND:
 899                         if (intvalue != 0) {
 900                                 dprintso(so, 1,
 901                                     ("sosdp_setsockopt: setting 0x%x\n",
 902                                     option_name));
 903                                 so->so_options |= option_name;
 904                         } else {
 905                                 dprintso(so, 1,
 906                                     ("sosdp_setsockopt: clearing 0x%x\n",
 907                                     option_name));
 908                                 so->so_options &= ~option_name;
 909                         }
 910                         break;
 911 
 912                 case SO_SNDBUF:
 913                         so->so_sndbuf = intvalue;
 914                         if (so->so_sndlowat > so->so_sndbuf) {
 915                                 so->so_sndlowat = so->so_sndbuf;
 916                         }
 917                         break;
 918                 case SO_RCVBUF:
 919                         so->so_rcvbuf = intvalue;
 920                         if (so->so_rcvlowat > so->so_rcvbuf) {
 921                                 so->so_rcvlowat = so->so_rcvbuf;
 922                         }
 923                         break;
 924                 case SO_SNDLOWAT:
 925                         if (so->so_sndlowat > so->so_sndbuf) {
 926                                 so->so_sndlowat = so->so_sndbuf;
 927                         }
 928                         break;
 929                 case SO_RCVLOWAT:
 930                         if (so->so_rcvlowat > so->so_rcvbuf) {
 931                                 so->so_rcvlowat = so->so_rcvbuf;
 932                         }
 933                         break;
 934                 }
 935 #undef  intvalue
 936 
 937                 if (error != 0) {
 938                         if ((error == ENOPROTOOPT || error == EPROTO ||
 939                             error == EINVAL) && handled) {
 940                                 dprintso(so, 1,
 941                                     ("sosdp_setsockopt: ignoring error %d "
 942                                     "for 0x%x\n", error, option_name));
 943                                 error = 0;
 944                         }
 945                 }
 946         }
 947 
 948 done:
 949         so_unlock_single(so, SOLOCKED);
 950         mutex_exit(&so->so_lock);
 951 
 952         return (error);
 953 }
 954 
 955 /* ARGSUSED */
 956 static int
 957 sosdp_ioctl(struct sonode *so, int cmd, intptr_t arg, int mode,
 958     struct cred *cr, int32_t *rvalp)
 959 {
 960         int32_t value;
 961         int error, intval;
 962         pid_t pid;
 963 
 964         /* handle socket specific ioctls */
 965         switch (cmd) {
 966         case FIONBIO:
 967                 if (so_copyin((void *)arg, &value, sizeof (int32_t),
 968                     (mode & (int)FKIOCTL))) {
 969                         return (EFAULT);
 970                 }
 971                 mutex_enter(&so->so_lock);
 972                 if (value != 0) {
 973                         so->so_state |= SS_NDELAY;
 974                 } else {
 975                         so->so_state &= ~SS_NDELAY;
 976                 }
 977                 mutex_exit(&so->so_lock);
 978                 return (0);
 979 
 980         case FIOASYNC:
 981                 if (so_copyin((void *)arg, &value, sizeof (int32_t),
 982                     (mode & (int)FKIOCTL))) {
 983                         return (EFAULT);
 984                 }
 985                 mutex_enter(&so->so_lock);
 986 
 987                 if (value) {
 988                         /* Turn on SIGIO */
 989                         so->so_state |= SS_ASYNC;
 990                 } else {
 991                         /* Turn off SIGIO */
 992                         so->so_state &= ~SS_ASYNC;
 993                 }
 994                 mutex_exit(&so->so_lock);
 995                 return (0);
 996 
 997         case SIOCSPGRP:
 998         case FIOSETOWN:
 999                 if (so_copyin((void *)arg, &pid, sizeof (pid_t),
1000                     (mode & (int)FKIOCTL))) {
1001                         return (EFAULT);
1002                 }
1003                 mutex_enter(&so->so_lock);
1004 
1005                 error = (pid != so->so_pgrp) ? socket_chgpgrp(so, pid) : 0;
1006                 mutex_exit(&so->so_lock);
1007                 return (error);
1008 
1009         case SIOCGPGRP:
1010         case FIOGETOWN:
1011                 if (so_copyout(&so->so_pgrp, (void *)arg,
1012                     sizeof (pid_t), (mode & (int)FKIOCTL)))
1013                         return (EFAULT);
1014                 return (0);
1015 
1016         case SIOCATMARK:
1017                 intval = 0;
1018                 error = sdp_ioctl(
1019                     (struct sdp_conn_struct_t *)so->so_proto_handle, cmd,
1020                     &intval, cr);
1021                 if (so_copyout(&intval, (void *)arg, sizeof (int),
1022                     (mode & (int)FKIOCTL)))
1023                         return (EFAULT);
1024                 return (0);
1025 
1026 
1027         case SIOCSENABLESDP: {
1028                 int32_t enable;
1029 
1030                 /*
1031                  * System wide enable SDP
1032                  */
1033 
1034                 if (so_copyin((void *)arg, &enable, sizeof (int32_t),
1035                     mode & (int)FKIOCTL))
1036                         return (EFAULT);
1037 
1038                 error = sdp_ioctl(
1039                     (struct sdp_conn_struct_t *)so->so_proto_handle, cmd,
1040                     &enable, cr);
1041                 if (so_copyout(&enable, (void *)arg,
1042                     sizeof (int32_t), (mode & (int)FKIOCTL)))
1043                         return (EFAULT);
1044                 return (0);
1045         }
1046                 /* from strioctl */
1047         case FIONREAD:
1048                 /*
1049                  * Return number of bytes of data in all data messages
1050                  * in queue in "arg".
1051                  * For stream socket, amount of available data.
1052                  */
1053                 if (so->so_state & SS_ACCEPTCONN) {
1054                         intval = 0;
1055                 } else {
1056                         mutex_enter(&so->so_lock);
1057                         intval = sdp_polldata(
1058                             (struct sdp_conn_struct_t *)so->so_proto_handle,
1059                             SDP_READ);
1060                         mutex_exit(&so->so_lock);
1061                 }
1062                 if (so_copyout(&intval, (void *)arg, sizeof (intval),
1063                     (mode & (int)FKIOCTL)))
1064                         return (EFAULT);
1065                 return (0);
1066         default:
1067                 return (EINVAL);
1068         }
1069 }
1070 
1071 /*
1072  * Check socktpi_poll() on why so_lock is not held in this function.
1073  */
1074 static int
1075 sosdp_poll(struct sonode *so, short events, int anyyet, short *reventsp,
1076     struct pollhead **phpp)
1077 {
1078         short origevents = events;
1079         int so_state;
1080 
1081         so_state = so->so_state;
1082 
1083         ASSERT(so->so_version != SOV_STREAM);
1084 
1085         if (!(so_state & SS_ISCONNECTED) && (so->so_type == SOCK_STREAM)) {
1086                 /*
1087                  * Not connected yet - turn off write side events
1088                  */
1089                 events &= ~(POLLOUT|POLLWRBAND);
1090         }
1091 
1092         /*
1093          * Check for errors
1094          */
1095         if (so->so_error != 0 &&
1096             ((POLLIN|POLLRDNORM|POLLOUT) & origevents) != 0) {
1097                 *reventsp = (POLLIN|POLLRDNORM|POLLOUT) & origevents;
1098                 goto done;
1099         }
1100 
1101         *reventsp = 0;
1102         if (so->so_type != SOCK_STREAM) {
1103                 goto done;
1104         }
1105 
1106         /*
1107          * Don't mark socket writable until TX queued data is below watermark.
1108          */
1109         if (sdp_polldata((struct sdp_conn_struct_t *)so->so_proto_handle,
1110             SDP_XMIT)) {
1111                 *reventsp |= POLLOUT & events;
1112         }
1113 
1114         if (sdp_polldata((struct sdp_conn_struct_t *)so->so_proto_handle,
1115             SDP_READ)) {
1116                 *reventsp |= (POLLIN|POLLRDNORM) & events;
1117         }
1118 
1119         if ((so_state & SS_CANTRCVMORE) || (so->so_acceptq_len > 0)) {
1120                 *reventsp |= (POLLIN|POLLRDNORM) & events;
1121         }
1122 
1123 done:
1124         if ((*reventsp == 0 && !anyyet) || (events & POLLET)) {
1125                 *phpp = &so->so_poll_list;
1126         }
1127 
1128         return (0);
1129 }
1130 
1131 /* ARGSUSED */
1132 static int
1133 sosdp_close(struct sonode *so, int flag, struct cred *cr)
1134 {
1135         int error = 0;
1136 
1137         mutex_enter(&so->so_lock);
1138         so_lock_single(so);
1139         /*
1140          * Need to set flags as there might be ops in progress on
1141          * this socket.
1142          *
1143          * If socket already disconnected/disconnecting,
1144          * don't send signal (again).
1145          */
1146         soisdisconnected(so, 0);
1147         mutex_exit(&so->so_lock);
1148 
1149         /*
1150          * Initiate connection shutdown.
1151          */
1152         error = sdp_disconnect((struct sdp_conn_struct_t *)so->so_proto_handle,
1153             flag);
1154 
1155         mutex_enter(&so->so_lock);
1156         so_unlock_single(so, SOLOCKED);
1157         so_notify_disconnected(so, B_FALSE, error);
1158 
1159         return (error);
1160 }
1161 
1162 /* ARGSUSED */
1163 void
1164 sosdp_fini(struct sonode *so, struct cred *cr)
1165 {
1166         dprint(3, ("sosdp_fini: so:%p so_proto_handle:%p", (void *)so,
1167             (void *)so->so_proto_handle));
1168 
1169         ASSERT(so->so_ops == &sosdp_sonodeops);
1170 
1171         if (so->so_proto_handle != NULL)
1172                 sdp_close((struct sdp_conn_struct_t *)so->so_proto_handle);
1173         so->so_proto_handle = NULL;
1174 
1175         mutex_enter(&so->so_lock);
1176 
1177         so_acceptq_flush(so, B_TRUE);
1178 
1179         mutex_exit(&so->so_lock);
1180 
1181         sonode_fini(so);
1182 }
1183 
1184 /*
1185  * Upcalls from SDP
1186  */
1187 
1188 /*
1189  * Incoming connection on listen socket.
1190  */
1191 static void *
1192 sdp_sock_newconn(void *parenthandle, void *connind)
1193 {
1194         struct sonode *lso = parenthandle;
1195         struct sonode *nso;
1196         int error;
1197 
1198         ASSERT(lso->so_state & SS_ACCEPTCONN);
1199         ASSERT(lso->so_proto_handle != NULL); /* closed conn */
1200         ASSERT(lso->so_type == SOCK_STREAM);
1201 
1202         dprint(3, ("sosdp_newconn A: so:%p so_proto_handle:%p", (void *)lso,
1203             (void *)lso->so_proto_handle));
1204 
1205         /*
1206          * Check current # of queued conns against backlog
1207          */
1208         if (lso->so_rcv_queued >= lso->so_backlog) {
1209                 return (NULL);
1210         }
1211 
1212         nso = socket_newconn(lso, connind, NULL, SOCKET_NOSLEEP, &error);
1213         if (nso == NULL) {
1214                 eprintsoline(lso, error);
1215                 return (NULL);
1216         }
1217 
1218         dprint(2, ("sdp_stream_newconn: new %p\n", (void *)nso));
1219 
1220         (void) so_acceptq_enqueue(lso, nso);
1221 
1222         mutex_enter(&lso->so_lock);
1223         so_notify_newconn(lso);
1224         return (nso);
1225 }
1226 
1227 /*
1228  * For outgoing connections, the connection has been established.
1229  */
1230 static void
1231 sdp_sock_connected(void *handle)
1232 {
1233         struct sonode *so = handle;
1234 
1235         ASSERT(so->so_type == SOCK_STREAM);
1236         dprint(3, ("sosdp_connected C: so:%p so_proto_handle:%p", (void *)so,
1237             (void *)so->so_proto_handle));
1238 
1239         mutex_enter(&so->so_lock);
1240         ASSERT(so->so_proto_handle); /* closed conn */
1241 
1242         ASSERT(!(so->so_state & SS_ACCEPTCONN));
1243         soisconnected(so);
1244 
1245         so_notify_connected(so);
1246 }
1247 
1248 /*
1249  * Connection got disconnected. Either with an error, or through
1250  * normal handshake.
1251  */
1252 static void
1253 sdp_sock_disconnected(void *handle, int error)
1254 {
1255         struct sonode *so = handle;
1256 
1257         ASSERT(so->so_type == SOCK_STREAM);
1258         dprint(2, ("sosdp_disconnected C: so:%p so_proto_handle:%p error:%d",
1259             (void *)so, (void *)so->so_proto_handle, error));
1260 
1261         mutex_enter(&so->so_lock);
1262         ASSERT(so->so_proto_handle != NULL); /* closed conn */
1263 
1264         soisdisconnected(so, error);
1265         so_notify_disconnected(so, B_FALSE, error);
1266 }
1267 
1268 /*
1269  * Incoming data.
1270  */
1271 /*ARGSUSED*/
1272 static int
1273 sdp_sock_recv(void *handle, mblk_t *mp, int flags)
1274 {
1275         struct sonode *so = handle;
1276 
1277         ASSERT(so->so_type == SOCK_STREAM);
1278 
1279         mutex_enter(&so->so_lock);
1280         so_notify_data(so, 0);
1281 
1282         return (so->so_rcvbuf);
1283 }
1284 
1285 /*
1286  * TX queued data got acknowledged.
1287  */
1288 static void
1289 sdp_sock_xmitted(void *handle, int writeable)
1290 {
1291         struct sonode *so = handle;
1292 
1293         dprint(4, ("sosdp_sock_xmitted: so:%p so_proto_handle:%p txq:%d",
1294             (void *)so, (void *)so->so_proto_handle, writeable));
1295         mutex_enter(&so->so_lock);
1296         ASSERT(so->so_proto_handle != NULL); /* closed conn */
1297 
1298 
1299         /*
1300          * Only do pollwakeup if the amount of queued data is less than
1301          * watermark.
1302          */
1303         if (!writeable) {
1304                 so_notify_writable(so);
1305         } else {
1306                 mutex_exit(&so->so_lock);
1307         }
1308 }
1309 
1310 
1311 /*
1312  * SDP notifies socket for presence of urgent data.
1313  */
1314 static void
1315 sdp_sock_urgdata(void *handle)
1316 {
1317         struct sonode *so = handle;
1318 
1319         ASSERT(so->so_type == SOCK_STREAM);
1320 
1321         mutex_enter(&so->so_lock);
1322 
1323         ASSERT(so->so_proto_handle != NULL); /* closed conn */
1324         so_notify_oobsig(so);
1325 }
1326 
1327 /*
1328  * SDP notifies socket about receiving of conn close request from peer side.
1329  */
1330 static void
1331 sdp_sock_ordrel(void *handle)
1332 {
1333         struct sonode *so = handle;
1334 
1335         ASSERT(so->so_type == SOCK_STREAM);
1336 
1337         dprint(4, ("sdp_sock_ordrel : so:%p, so_proto_handle:%p",
1338             (void *)so, (void *)so->so_proto_handle));
1339         mutex_enter(&so->so_lock);
1340         socantrcvmore(so);
1341         so_notify_eof(so);
1342 }
1343 
1344 static void
1345 sdp_sock_connfail(void *handle, int error)
1346 {
1347         struct sonode *so = handle;
1348 
1349         dprint(3, ("sosdp_conn Failed: so:%p so_proto_handle:%p", (void *)so,
1350             (void *)so->so_proto_handle));
1351         mutex_enter(&so->so_lock);
1352         ASSERT(so->so_proto_handle != NULL); /* closed conn */
1353         so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
1354         so->so_error = (ushort_t)error;
1355         mutex_exit(&so->so_lock);
1356         cv_broadcast(&so->so_state_cv);
1357 }