* socreate returns a socket with a ref count of 1. The socket should be * closed with soclose(). */
| 503 | * closed with soclose(). |
| 504 | */ |
| 505 | int |
| 506 | socreate(int dom, struct socket **aso, int type, int proto, |
| 507 | struct ucred *cred, struct thread *td) |
| 508 | { |
| 509 | struct protosw *prp; |
| 510 | struct socket *so; |
| 511 | int error; |
| 512 | |
| 513 | if (proto) |
| 514 | prp = pffindproto(dom, proto, type); |
| 515 | else |
| 516 | prp = pffindtype(dom, type); |
| 517 | |
| 518 | if (prp == NULL) { |
| 519 | /* No support for domain. */ |
| 520 | if (pffinddomain(dom) == NULL) |
| 521 | return (EAFNOSUPPORT); |
| 522 | /* No support for socket type. */ |
| 523 | if (proto == 0 && type != 0) |
| 524 | return (EPROTOTYPE); |
| 525 | return (EPROTONOSUPPORT); |
| 526 | } |
| 527 | if (prp->pr_usrreqs->pru_attach == NULL || |
| 528 | prp->pr_usrreqs->pru_attach == pru_attach_notsupp) |
| 529 | return (EPROTONOSUPPORT); |
| 530 | |
| 531 | if (prison_check_af(cred, prp->pr_domain->dom_family) != 0) |
| 532 | return (EPROTONOSUPPORT); |
| 533 | |
| 534 | if (prp->pr_type != type) |
| 535 | return (EPROTOTYPE); |
| 536 | so = soalloc(CRED_TO_VNET(cred)); |
| 537 | if (so == NULL) |
| 538 | return (ENOBUFS); |
| 539 | |
| 540 | so->so_type = type; |
| 541 | so->so_cred = crhold(cred); |
| 542 | if ((prp->pr_domain->dom_family == PF_INET) || |
| 543 | (prp->pr_domain->dom_family == PF_INET6) || |
| 544 | (prp->pr_domain->dom_family == PF_ROUTE)) |
| 545 | so->so_fibnum = td->td_proc->p_fibnum; |
| 546 | else |
| 547 | so->so_fibnum = 0; |
| 548 | so->so_proto = prp; |
| 549 | #ifdef MAC |
| 550 | mac_socket_create(cred, so); |
| 551 | #endif |
| 552 | knlist_init(&so->so_rdsel.si_note, so, so_rdknl_lock, so_rdknl_unlock, |
| 553 | so_rdknl_assert_lock); |
| 554 | knlist_init(&so->so_wrsel.si_note, so, so_wrknl_lock, so_wrknl_unlock, |
| 555 | so_wrknl_assert_lock); |
| 556 | /* |
| 557 | * Auto-sizing of socket buffers is managed by the protocols and |
| 558 | * the appropriate flags must be set in the pru_attach function. |
| 559 | */ |
| 560 | CURVNET_SET(so->so_vnet); |
| 561 | error = (*prp->pr_usrreqs->pru_attach)(so, proto, td); |
| 562 | CURVNET_RESTORE(); |
no test coverage detected