458 so->so_oobmsg = NULL;
459
460 so->so_proto_handle = NULL;
461
462 so->so_peercred = NULL;
463
464 so->so_rcv_queued = 0;
465 so->so_rcv_q_head = NULL;
466 so->so_rcv_q_last_head = NULL;
467 so->so_rcv_head = NULL;
468 so->so_rcv_last_head = NULL;
469 so->so_rcv_wanted = 0;
470 so->so_rcv_timer_interval = SOCKET_NO_RCVTIMER;
471 so->so_rcv_timer_tid = 0;
472 so->so_rcv_thresh = 0;
473
474 list_create(&so->so_acceptq_list, sizeof (struct sonode),
475 offsetof(struct sonode, so_acceptq_node));
476 list_create(&so->so_acceptq_defer, sizeof (struct sonode),
477 offsetof(struct sonode, so_acceptq_node));
478 list_link_init(&so->so_acceptq_node);
479 so->so_acceptq_len = 0;
480 so->so_backlog = 0;
481 so->so_listener = NULL;
482
483 so->so_snd_qfull = B_FALSE;
484
485 so->so_filter_active = 0;
486 so->so_filter_tx = 0;
487 so->so_filter_defertime = 0;
488 so->so_filter_top = NULL;
489 so->so_filter_bottom = NULL;
490
491 mutex_init(&so->so_lock, NULL, MUTEX_DEFAULT, NULL);
492 mutex_init(&so->so_acceptq_lock, NULL, MUTEX_DEFAULT, NULL);
493 rw_init(&so->so_fallback_rwlock, NULL, RW_DEFAULT, NULL);
494 cv_init(&so->so_state_cv, NULL, CV_DEFAULT, NULL);
495 cv_init(&so->so_single_cv, NULL, CV_DEFAULT, NULL);
496 cv_init(&so->so_read_cv, NULL, CV_DEFAULT, NULL);
497
498 cv_init(&so->so_acceptq_cv, NULL, CV_DEFAULT, NULL);
499 cv_init(&so->so_snd_cv, NULL, CV_DEFAULT, NULL);
500 cv_init(&so->so_rcv_cv, NULL, CV_DEFAULT, NULL);
501 cv_init(&so->so_copy_cv, NULL, CV_DEFAULT, NULL);
502 cv_init(&so->so_closing_cv, NULL, CV_DEFAULT, NULL);
503
504 return (0);
505 }
506
507 /*ARGSUSED*/
508 void
509 sonode_destructor(void *buf, void *cdrarg)
510 {
511 struct sonode *so = buf;
512 struct vnode *vp = SOTOV(so);
513
514 ASSERT(so->so_priv == NULL);
515 ASSERT(so->so_peercred == NULL);
516
517 ASSERT(so->so_oobmsg == NULL);
518
519 ASSERT(so->so_rcv_q_head == NULL);
520
521 list_destroy(&so->so_acceptq_list);
522 list_destroy(&so->so_acceptq_defer);
523 ASSERT(!list_link_active(&so->so_acceptq_node));
524 ASSERT(so->so_listener == NULL);
525
526 ASSERT(so->so_filter_active == 0);
527 ASSERT(so->so_filter_tx == 0);
528 ASSERT(so->so_filter_top == NULL);
529 ASSERT(so->so_filter_bottom == NULL);
530
531 ASSERT(vp->v_data == so);
532 ASSERT(vn_matchops(vp, socket_vnodeops));
533
534 vn_free(vp);
535
536 mutex_destroy(&so->so_lock);
537 mutex_destroy(&so->so_acceptq_lock);
538 rw_destroy(&so->so_fallback_rwlock);
539
540 cv_destroy(&so->so_state_cv);
541 cv_destroy(&so->so_single_cv);
542 cv_destroy(&so->so_read_cv);
543 cv_destroy(&so->so_acceptq_cv);
544 cv_destroy(&so->so_snd_cv);
545 cv_destroy(&so->so_rcv_cv);
546 cv_destroy(&so->so_closing_cv);
547 }
548
549 void
550 sonode_init(struct sonode *so, struct sockparams *sp, int family,
551 int type, int protocol, sonodeops_t *sops)
552 {
553 vnode_t *vp;
554
555 vp = SOTOV(so);
556
557 so->so_flag = 0;
609 so->so_flowctrld = B_FALSE;
610
611 so->so_pollev = 0;
612 bzero(&so->so_poll_list, sizeof (so->so_poll_list));
613 bzero(&so->so_proto_props, sizeof (struct sock_proto_props));
614
615 bzero(&(so->so_ksock_callbacks), sizeof (ksocket_callbacks_t));
616 so->so_ksock_cb_arg = NULL;
617
618 so->so_max_addr_len = sizeof (struct sockaddr_storage);
619
620 so->so_direct = NULL;
621
622 vn_exists(vp);
623 }
624
625 void
626 sonode_fini(struct sonode *so)
627 {
628 vnode_t *vp;
629
630 ASSERT(so->so_count == 0);
631
632 if (so->so_rcv_timer_tid) {
633 ASSERT(MUTEX_NOT_HELD(&so->so_lock));
634 (void) untimeout(so->so_rcv_timer_tid);
635 so->so_rcv_timer_tid = 0;
636 }
637
638 if (so->so_poll_list.ph_list != NULL) {
639 pollwakeup(&so->so_poll_list, POLLERR);
640 pollhead_clean(&so->so_poll_list);
641 }
642
643 if (so->so_direct != NULL)
644 sod_sock_fini(so);
645
646 vp = SOTOV(so);
647 vn_invalid(vp);
648
649 if (so->so_peercred != NULL) {
650 crfree(so->so_peercred);
651 so->so_peercred = NULL;
652 }
653 /* Detach and destroy filters */
654 if (so->so_filter_top != NULL)
655 sof_sonode_cleanup(so);
656
657 ASSERT(list_is_empty(&so->so_acceptq_list));
658 ASSERT(list_is_empty(&so->so_acceptq_defer));
659 ASSERT(!list_link_active(&so->so_acceptq_node));
660
661 ASSERT(so->so_rcv_queued == 0);
662 ASSERT(so->so_rcv_q_head == NULL);
663 ASSERT(so->so_rcv_q_last_head == NULL);
664 ASSERT(so->so_rcv_head == NULL);
665 ASSERT(so->so_rcv_last_head == NULL);
666 }
|
458 so->so_oobmsg = NULL;
459
460 so->so_proto_handle = NULL;
461
462 so->so_peercred = NULL;
463
464 so->so_rcv_queued = 0;
465 so->so_rcv_q_head = NULL;
466 so->so_rcv_q_last_head = NULL;
467 so->so_rcv_head = NULL;
468 so->so_rcv_last_head = NULL;
469 so->so_rcv_wanted = 0;
470 so->so_rcv_timer_interval = SOCKET_NO_RCVTIMER;
471 so->so_rcv_timer_tid = 0;
472 so->so_rcv_thresh = 0;
473
474 list_create(&so->so_acceptq_list, sizeof (struct sonode),
475 offsetof(struct sonode, so_acceptq_node));
476 list_create(&so->so_acceptq_defer, sizeof (struct sonode),
477 offsetof(struct sonode, so_acceptq_node));
478 avl_create(&so->so_pid_tree, pid_node_comparator, sizeof (pid_node_t),
479 offsetof(pid_node_t, pn_ref_link));
480 list_link_init(&so->so_acceptq_node);
481 so->so_acceptq_len = 0;
482 so->so_backlog = 0;
483 so->so_listener = NULL;
484
485 so->so_snd_qfull = B_FALSE;
486
487 so->so_filter_active = 0;
488 so->so_filter_tx = 0;
489 so->so_filter_defertime = 0;
490 so->so_filter_top = NULL;
491 so->so_filter_bottom = NULL;
492
493 mutex_init(&so->so_lock, NULL, MUTEX_DEFAULT, NULL);
494 mutex_init(&so->so_acceptq_lock, NULL, MUTEX_DEFAULT, NULL);
495 mutex_init(&so->so_pid_tree_lock, NULL, MUTEX_DEFAULT, NULL);
496 rw_init(&so->so_fallback_rwlock, NULL, RW_DEFAULT, NULL);
497 cv_init(&so->so_state_cv, NULL, CV_DEFAULT, NULL);
498 cv_init(&so->so_single_cv, NULL, CV_DEFAULT, NULL);
499 cv_init(&so->so_read_cv, NULL, CV_DEFAULT, NULL);
500
501 cv_init(&so->so_acceptq_cv, NULL, CV_DEFAULT, NULL);
502 cv_init(&so->so_snd_cv, NULL, CV_DEFAULT, NULL);
503 cv_init(&so->so_rcv_cv, NULL, CV_DEFAULT, NULL);
504 cv_init(&so->so_copy_cv, NULL, CV_DEFAULT, NULL);
505 cv_init(&so->so_closing_cv, NULL, CV_DEFAULT, NULL);
506
507 return (0);
508 }
509
510 /*ARGSUSED*/
511 void
512 sonode_destructor(void *buf, void *cdrarg)
513 {
514 struct sonode *so = buf;
515 struct vnode *vp = SOTOV(so);
516
517 ASSERT(so->so_priv == NULL);
518 ASSERT(so->so_peercred == NULL);
519
520 ASSERT(so->so_oobmsg == NULL);
521
522 ASSERT(so->so_rcv_q_head == NULL);
523
524 list_destroy(&so->so_acceptq_list);
525 list_destroy(&so->so_acceptq_defer);
526 avl_destroy(&so->so_pid_tree);
527 ASSERT(!list_link_active(&so->so_acceptq_node));
528 ASSERT(so->so_listener == NULL);
529
530 ASSERT(so->so_filter_active == 0);
531 ASSERT(so->so_filter_tx == 0);
532 ASSERT(so->so_filter_top == NULL);
533 ASSERT(so->so_filter_bottom == NULL);
534
535 ASSERT(vp->v_data == so);
536 ASSERT(vn_matchops(vp, socket_vnodeops));
537
538 vn_free(vp);
539
540 mutex_destroy(&so->so_lock);
541 mutex_destroy(&so->so_acceptq_lock);
542 mutex_destroy(&so->so_pid_tree_lock);
543 rw_destroy(&so->so_fallback_rwlock);
544
545 cv_destroy(&so->so_state_cv);
546 cv_destroy(&so->so_single_cv);
547 cv_destroy(&so->so_read_cv);
548 cv_destroy(&so->so_acceptq_cv);
549 cv_destroy(&so->so_snd_cv);
550 cv_destroy(&so->so_rcv_cv);
551 cv_destroy(&so->so_closing_cv);
552 }
553
554 void
555 sonode_init(struct sonode *so, struct sockparams *sp, int family,
556 int type, int protocol, sonodeops_t *sops)
557 {
558 vnode_t *vp;
559
560 vp = SOTOV(so);
561
562 so->so_flag = 0;
614 so->so_flowctrld = B_FALSE;
615
616 so->so_pollev = 0;
617 bzero(&so->so_poll_list, sizeof (so->so_poll_list));
618 bzero(&so->so_proto_props, sizeof (struct sock_proto_props));
619
620 bzero(&(so->so_ksock_callbacks), sizeof (ksocket_callbacks_t));
621 so->so_ksock_cb_arg = NULL;
622
623 so->so_max_addr_len = sizeof (struct sockaddr_storage);
624
625 so->so_direct = NULL;
626
627 vn_exists(vp);
628 }
629
630 void
631 sonode_fini(struct sonode *so)
632 {
633 vnode_t *vp;
634 pid_node_t *pn;
635
636 ASSERT(so->so_count == 0);
637
638 if (so->so_rcv_timer_tid) {
639 ASSERT(MUTEX_NOT_HELD(&so->so_lock));
640 (void) untimeout(so->so_rcv_timer_tid);
641 so->so_rcv_timer_tid = 0;
642 }
643
644 if (so->so_poll_list.ph_list != NULL) {
645 pollwakeup(&so->so_poll_list, POLLERR);
646 pollhead_clean(&so->so_poll_list);
647 }
648
649 if (so->so_direct != NULL)
650 sod_sock_fini(so);
651
652 vp = SOTOV(so);
653 vn_invalid(vp);
654
655 if (so->so_peercred != NULL) {
656 crfree(so->so_peercred);
657 so->so_peercred = NULL;
658 }
659 /* Detach and destroy filters */
660 if (so->so_filter_top != NULL)
661 sof_sonode_cleanup(so);
662
663 mutex_enter(&so->so_pid_tree_lock);
664 while ((pn = avl_first(&so->so_pid_tree)) != NULL) {
665 avl_remove(&so->so_pid_tree, pn);
666 kmem_free(pn, sizeof (*pn));
667 }
668 mutex_exit(&so->so_pid_tree_lock);
669
670 ASSERT(list_is_empty(&so->so_acceptq_list));
671 ASSERT(list_is_empty(&so->so_acceptq_defer));
672 ASSERT(!list_link_active(&so->so_acceptq_node));
673
674 ASSERT(so->so_rcv_queued == 0);
675 ASSERT(so->so_rcv_q_head == NULL);
676 ASSERT(so->so_rcv_q_last_head == NULL);
677 ASSERT(so->so_rcv_head == NULL);
678 ASSERT(so->so_rcv_last_head == NULL);
679 }
680
681 void
682 sonode_insert_pid(struct sonode *so, pid_t pid)
683 {
684 pid_node_t *pn, lookup_pn;
685 avl_index_t idx_pn;
686
687 lookup_pn.pn_pid = pid;
688 mutex_enter(&so->so_pid_tree_lock);
689 pn = avl_find(&so->so_pid_tree, &lookup_pn, &idx_pn);
690
691 if (pn != NULL) {
692 pn->pn_count++;
693 } else {
694 pn = kmem_zalloc(sizeof (*pn), KM_SLEEP);
695 pn->pn_pid = pid;
696 pn->pn_count = 1;
697 avl_insert(&so->so_pid_tree, pn, idx_pn);
698 }
699 mutex_exit(&so->so_pid_tree_lock);
700 }
701
702 void
703 sonode_remove_pid(struct sonode *so, pid_t pid)
704 {
705 pid_node_t *pn, lookup_pn;
706
707 lookup_pn.pn_pid = pid;
708 mutex_enter(&so->so_pid_tree_lock);
709 pn = avl_find(&so->so_pid_tree, &lookup_pn, NULL);
710
711 if (pn != NULL) {
712 if (pn->pn_count > 1) {
713 pn->pn_count--;
714 } else {
715 avl_remove(&so->so_pid_tree, pn);
716 kmem_free(pn, sizeof (*pn));
717 }
718 }
719 mutex_exit(&so->so_pid_tree_lock);
720 }
|