static int natm_usr_attach(struct socket *so, int proto) { struct natmpcb *npcb; int error = 0; int s = SPLSOFTNET(); npcb = (struct natmpcb *) so->so_pcb; if (npcb) { error = EISCONN; goto out; } if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { if (proto == PROTO_NATMAAL5) error = soreserve(so, natm5_sendspace, natm5_recvspace); else error = soreserve(so, natm0_sendspace, natm0_recvspace); if (error) goto out; } so->so_pcb = (caddr_t) (npcb = npcb_alloc(M_WAITOK)); npcb->npcb_socket = so; out: splx(s); return (error); }
static int lpx_USER_r_attach( struct socket *so, int proto, struct proc *td ) { int error = 0; int s; struct lpxpcb *lpxp = sotolpxpcb(so); if (td != NULL && (error = suser(td->p_ucred, &td->p_acflag)) != 0) return (error); s = splnet(); error = Lpx_PCB_alloc(so, &lpxrawpcb, td); splx(s); if (error) return (error); error = soreserve(so, lpxsendspace, lpxrecvspace); if (error) return (error); lpxp = sotolpxpcb(so); lpxp->lpxp_faddr.x_host = lpx_broadhost; lpxp->lpxp_flags = LPXP_RAWIN | LPXP_RAWOUT; return (error); }
/* * Adds a socket to the list for servicing by nfscbds. */ int nfscbd_addsock(struct file *fp) { int siz; struct socket *so; int error; SVCXPRT *xprt; so = fp->f_data; siz = sb_max_adj; error = soreserve(so, siz, siz); if (error) return (error); /* * Steal the socket from userland so that it doesn't close * unexpectedly. */ if (so->so_type == SOCK_DGRAM) xprt = svc_dg_create(nfscbd_pool, so, 0, 0); else xprt = svc_vc_create(nfscbd_pool, so, 0, 0); if (xprt) { fp->f_ops = &badfileops; fp->f_data = NULL; svc_reg(xprt, NFS_CALLBCKPROG, NFSV4_CBVERS, nfscb_program, NULL); SVC_RELEASE(xprt); } return (0); }
/* * Allocate a control block and a nominal amount of buffer space for the * socket. */ int raw_attach(struct socket *so, int proto) { struct rawcb *rp = sotorawcb(so); int error; /* * It is assumed that raw_attach is called after space has been * allocated for the rawcb; consumer protocols may simply allocate * type struct rawcb, or a wrapper data structure that begins with a * struct rawcb. */ KASSERT(rp != NULL, ("raw_attach: rp == NULL")); error = soreserve(so, raw_sendspace, raw_recvspace); if (error) return (error); rp->rcb_socket = so; rp->rcb_proto.sp_family = so->so_proto->pr_domain->dom_family; rp->rcb_proto.sp_protocol = proto; mtx_lock(&rawcb_mtx); LIST_INSERT_HEAD(&V_rawcb_list, rp, list); mtx_unlock(&rawcb_mtx); return (0); }
static int lpx_USER_attach( struct socket *so, int proto, struct proc *td ) { int error; int s; struct lpxpcb *lpxp = sotolpxpcb(so); if (lpxp != NULL) return (EINVAL); s = splnet(); error = Lpx_PCB_alloc(so, &lpxpcb, td); splx(s); if (error == 0) { int lpxsends, lpxrecvs; lpxsends = 256 * 1024; lpxrecvs = 256 * 1024; while(lpxsends > 0 && lpxrecvs > 0) { error = soreserve(so, lpxsends, lpxrecvs); if(error == 0) break; lpxsends -= (1024*2); lpxrecvs -= (1024*2); } DEBUG_CALL(4, ("lpxsends = %d\n", lpxsends/1024)); // error = soreserve(so, lpxsendspace, lpxrecvspace); } return (error); }
static int ps_attach(struct socket *so, int proto, struct thread *td) { struct pspcb *psp = sotopspcb(so); int error; PS_PRINTF(PS_DEBUG_SOCKET, "so = %p, proto=%d\n", so, proto); if (NULL != psp) return (EISCONN); error = soreserve(so, ps_sendspace, ps_recvspace); if (error) return (error); psp = malloc(sizeof(struct pspcb), M_PCB, M_WAITOK | M_ZERO); rw_init(&psp->psp_lock, "psp_lock"); psp->psp_ifp = NULL; so->so_pcb = (caddr_t)psp; psp->psp_socket = so; mtx_lock(pspcb_lock); LIST_INSERT_HEAD(pspcbhead, psp, psp_list); mtx_unlock(pspcb_lock); return (0); }
static int rfcomm_attach(struct socket *so, int proto) { int error; KASSERT(so->so_pcb == NULL); if (so->so_lock == NULL) { mutex_obj_hold(bt_lock); so->so_lock = bt_lock; solock(so); } KASSERT(solocked(so)); /* * Since we have nothing to add, we attach the DLC * structure directly to our PCB pointer. */ error = soreserve(so, rfcomm_sendspace, rfcomm_recvspace); if (error) return error; error = rfcomm_attach_pcb((struct rfcomm_dlc **)&so->so_pcb, &rfcomm_proto, so); if (error) return error; error = rfcomm_rcvd_pcb(so->so_pcb, sbspace(&so->so_rcv)); if (error) { rfcomm_detach_pcb((struct rfcomm_dlc **)&so->so_pcb); return error; } return 0; }
static int send_attach(struct socket *so, int proto, struct thread *td) { int error; SEND_LOCK(); if (V_send_so != NULL) { SEND_UNLOCK(); return (EEXIST); } error = priv_check(td, PRIV_NETINET_RAW); if (error) { SEND_UNLOCK(); return(error); } if (proto != IPPROTO_SEND) { SEND_UNLOCK(); return (EPROTONOSUPPORT); } error = soreserve(so, send_sendspace, send_recvspace); if (error) { SEND_UNLOCK(); return(error); } V_send_so = so; SEND_UNLOCK(); return (0); }
static int lpx_datagram_user_attach( struct socket *so, int proto, struct proc *td ) { int error; // int s; struct lpxpcb *lpxp = sotolpxpcb(so); if (lpxp != 0) panic("lpx_datagram_user_attach: so %x lpxpcb=%x\n", so, lpxp); // s = splnet(); error = Lpx_PCB_alloc(so, &lpx_datagram_pcb, td); // splx(s); if (error == 0) { int lpxsends, lpxrecvs; lpxsends = 256 * 1024; lpxrecvs = 256 * 1024; while (lpxsends > 0 && lpxrecvs > 0) { error = soreserve(so, lpxsends, lpxrecvs); if (error == 0) break; lpxsends -= (1024*2); lpxrecvs -= (1024*2); } DEBUG_PRINT(4, ("lpxsends = %d\n", lpxsends/1024)); // error = soreserve(so, lpxsendspace, lpxrecvspace); } return (error); }
static int userfw_soattach(struct socket *so, int proto, struct thread *td) { struct userfwpcb *pcb = sotopcb(so); int err = 0; struct ucred *cred; if (pcb != NULL) return EISCONN; /* Reserve space for socket */ err = soreserve(so, sosndspace, sorcvspace); if (err != 0) return err; /* Allocate pcb */ pcb = malloc(sizeof(struct userfwpcb), M_PCB, M_WAITOK | M_ZERO); pcb->sock = so; cred = crhold(td->td_ucred); pcb->uid = cred->cr_uid; crfree(cred); so->so_pcb = (caddr_t)pcb; /* Add socket to list */ mtx_lock(&so_list_mtx); SLIST_INSERT_HEAD(so_list, pcb, next); mtx_unlock(&so_list_mtx); so->so_state = so->so_state | SS_ISCONNECTED; return 0; }
int tcp_attach(struct socket * so) { struct tcpcb * tp; struct inpcb * inp; int error; if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { error = soreserve(so, tcp_sendspace, tcp_recvspace); if (error) return (error); } error = in_pcballoc(so, &tcb); if (error) return (error); inp = sotoinpcb(so); tp = tcp_newtcpcb(inp); if (tp == 0) { int nofd = so->so_state & SS_NOFDREF; /* XXX */ so->so_state &= ~SS_NOFDREF; /* don't free the socket yet */ in_pcbdetach(inp); so->so_state |= nofd; return (ENOBUFS); } tp->t_state = TCPS_CLOSED; return (0); }
/* * Attach TCP protocol to socket, allocating * internet protocol control block, tcp control block, * bufer space, and entering LISTEN state if to accept connections. */ static int tcp_attach(struct socket *so) { struct tcpcb *tp; struct inpcb *inp; int error; #ifdef INET6 int isipv6 = INP_CHECK_SOCKAF(so, AF_INET6) != 0; #endif //printf("tcp_attach: called so->so_snd=0x%lx\n", (long)&so->so_snd); //printf("tcp_attach: called so->so_rcv=0x%lx\n", (long)&so->so_rcv); if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { //printf("tcp_attach: called 2\n"); error = soreserve(so, tcp_sendspace, tcp_recvspace); if (error) return (error); } //printf("tcp_attach: called 2\n"); so->so_rcv.sb_flags |= SB_AUTOSIZE; so->so_snd.sb_flags |= SB_AUTOSIZE; INP_INFO_WLOCK(&tcbinfo); error = in_pcballoc(so, &tcbinfo); if (error) { INP_INFO_WUNLOCK(&tcbinfo); return (error); } inp = sotoinpcb(so); #ifdef INET6 if (isipv6) { inp->inp_vflag |= INP_IPV6; inp->in6p_hops = -1; /* use kernel default */ } else #endif inp->inp_vflag |= INP_IPV4; //printf("tcp_attach: called 5\n"); tp = tcp_newtcpcb(inp); if (tp == NULL) { #ifdef INET6 if (isipv6) { in6_pcbdetach(inp); in6_pcbfree(inp); } else { #endif in_pcbdetach(inp); in_pcbfree(inp); #ifdef INET6 } #endif INP_INFO_WUNLOCK(&tcbinfo); return (ENOBUFS); } tp->t_state = TCPS_CLOSED; INP_UNLOCK(inp); INP_INFO_WUNLOCK(&tcbinfo); //printf("tcp_attach: called 10\n"); return (0); }
/* * When an attempt at a new connection is noted on a socket * which accepts connections, sonewconn is called. If the * connection is possible (subject to space constraints, etc.) * then we allocate a new structure, properly linked into the * data structure of the original socket, and return this. * Connstatus may be 0 or SS_ISCONNECTED. * * Must be called at splsoftnet() */ struct socket * sonewconn(struct socket *head, int connstatus) { struct socket *so; int soqueue = connstatus ? 1 : 0; splsoftassert(IPL_SOFTNET); if (mclpools[0].pr_nout > mclpools[0].pr_hardlimit * 95 / 100) return (NULL); if (head->so_qlen + head->so_q0len > head->so_qlimit * 3) return (NULL); so = pool_get(&socket_pool, PR_NOWAIT|PR_ZERO); if (so == NULL) return (NULL); so->so_type = head->so_type; so->so_options = head->so_options &~ SO_ACCEPTCONN; so->so_linger = head->so_linger; so->so_state = head->so_state | SS_NOFDREF; so->so_proto = head->so_proto; so->so_timeo = head->so_timeo; so->so_pgid = head->so_pgid; so->so_euid = head->so_euid; so->so_ruid = head->so_ruid; so->so_egid = head->so_egid; so->so_rgid = head->so_rgid; so->so_cpid = head->so_cpid; so->so_siguid = head->so_siguid; so->so_sigeuid = head->so_sigeuid; /* * Inherit watermarks but those may get clamped in low mem situations. */ if (soreserve(so, head->so_snd.sb_hiwat, head->so_rcv.sb_hiwat)) { pool_put(&socket_pool, so); return (NULL); } so->so_snd.sb_wat = head->so_snd.sb_wat; so->so_snd.sb_lowat = head->so_snd.sb_lowat; so->so_snd.sb_timeo = head->so_snd.sb_timeo; so->so_rcv.sb_wat = head->so_rcv.sb_wat; so->so_rcv.sb_lowat = head->so_rcv.sb_lowat; so->so_rcv.sb_timeo = head->so_rcv.sb_timeo; soqinsque(head, so, soqueue); if ((*so->so_proto->pr_usrreq)(so, PRU_ATTACH, NULL, NULL, NULL, curproc)) { (void) soqremque(so, soqueue); pool_put(&socket_pool, so); return (NULL); } if (connstatus) { sorwakeup(head); wakeup(&head->so_timeo); so->so_state |= connstatus; } return (so); }
/* * Attach TCP protocol to socket, allocating internet protocol control * block, tcp control block, bufer space, and entering LISTEN state * if to accept connections. */ static int tcp_attach(struct socket *so, struct pru_attach_info *ai) { struct tcpcb *tp; struct inpcb *inp; int error; int cpu; #ifdef INET6 int isipv6 = INP_CHECK_SOCKAF(so, AF_INET6) != 0; #endif if (so->so_snd.ssb_hiwat == 0 || so->so_rcv.ssb_hiwat == 0) { lwkt_gettoken(&so->so_rcv.ssb_token); error = soreserve(so, tcp_sendspace, tcp_recvspace, ai->sb_rlimit); lwkt_reltoken(&so->so_rcv.ssb_token); if (error) return (error); } atomic_set_int(&so->so_rcv.ssb_flags, SSB_AUTOSIZE); atomic_set_int(&so->so_snd.ssb_flags, SSB_AUTOSIZE); cpu = mycpu->gd_cpuid; /* * Set the default port for protocol processing. This will likely * change when we connect. */ error = in_pcballoc(so, &tcbinfo[cpu]); if (error) return (error); inp = so->so_pcb; #ifdef INET6 if (isipv6) { inp->inp_vflag |= INP_IPV6; inp->in6p_hops = -1; /* use kernel default */ } else #endif inp->inp_vflag |= INP_IPV4; tp = tcp_newtcpcb(inp); if (tp == NULL) { /* * Make sure the socket is destroyed by the pcbdetach. */ soreference(so); #ifdef INET6 if (isipv6) in6_pcbdetach(inp); else #endif in_pcbdetach(inp); sofree(so); /* from ref above */ return (ENOBUFS); } tp->t_state = TCPS_CLOSED; return (0); }
static int mpls_attach(struct socket *so, int proto) { int error = EOPNOTSUPP; sosetlock(so); if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { error = soreserve(so, 8192, 8192); } return error; }
static int natm_usr_attach(struct socket *so, int proto, struct thread *p) { struct natmpcb *npcb; int error = 0; npcb = (struct natmpcb *)so->so_pcb; KASSERT(npcb == NULL, ("natm_usr_attach: so_pcb != NULL")); if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { if (proto == PROTO_NATMAAL5) error = soreserve(so, natm5_sendspace, natm5_recvspace); else error = soreserve(so, natm0_sendspace, natm0_recvspace); if (error) return (error); } so->so_pcb = npcb = npcb_alloc(M_WAITOK); npcb->npcb_socket = so; return (error); }
static int mpls_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam, struct mbuf *control, struct lwp *l) { int error = EOPNOTSUPP; if ((req == PRU_ATTACH) && (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0)) { int s = splsoftnet(); error = soreserve(so, 8192, 8192); splx(s); } return error; }
int mpls_raw_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam, struct mbuf *control, struct proc *p) { int error = 0; #ifdef MPLS_DEBUG printf("mpls_raw_usrreq: called! (reqid=%d).\n", req); #endif /* MPLS_DEBUG */ if (req == PRU_CONTROL) return (mpls_control(so, (u_long)m, (caddr_t)nam, (struct ifnet *)control)); switch (req) { case PRU_ATTACH: if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { error = soreserve(so, mpls_raw_sendspace, mpls_raw_recvspace); if (error) break; } break; case PRU_DETACH: case PRU_BIND: case PRU_LISTEN: case PRU_CONNECT: case PRU_CONNECT2: case PRU_DISCONNECT: case PRU_SHUTDOWN: case PRU_RCVD: case PRU_SEND: case PRU_SENSE: case PRU_RCVOOB: case PRU_SENDOOB: case PRU_SOCKADDR: case PRU_PEERADDR: error = EOPNOTSUPP; break; default: panic("mpls_raw_usrreq"); } return (error); }
static int udp6_attach(struct socket *so, int proto, struct thread *td) { struct inpcb *inp; struct inpcbinfo *pcbinfo; int error; pcbinfo = udp_get_inpcbinfo(so->so_proto->pr_protocol); inp = sotoinpcb(so); KASSERT(inp == NULL, ("udp6_attach: inp != NULL")); if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { error = soreserve(so, udp_sendspace, udp_recvspace); if (error) return (error); } INP_INFO_WLOCK(pcbinfo); error = in_pcballoc(so, pcbinfo); if (error) { INP_INFO_WUNLOCK(pcbinfo); return (error); } inp = (struct inpcb *)so->so_pcb; inp->inp_vflag |= INP_IPV6; if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) inp->inp_vflag |= INP_IPV4; inp->in6p_hops = -1; /* use kernel default */ inp->in6p_cksum = -1; /* just to be sure */ /* * XXX: ugly!! * IPv4 TTL initialization is necessary for an IPv6 socket as well, * because the socket may be bound to an IPv6 wildcard address, * which may match an IPv4-mapped IPv6 address. */ inp->inp_ip_ttl = V_ip_defttl; error = udp_newudpcb(inp); if (error) { in_pcbdetach(inp); in_pcbfree(inp); INP_INFO_WUNLOCK(pcbinfo); return (error); } INP_WUNLOCK(inp); INP_INFO_WUNLOCK(pcbinfo); return (0); }
/* * Adds a socket to the list for servicing by nfsds. */ int nfsrvd_addsock(struct file *fp) { int siz; struct socket *so; int error = 0; SVCXPRT *xprt; static u_int64_t sockref = 0; so = fp->f_data; siz = sb_max_adj; error = soreserve(so, siz, siz); if (error) goto out; /* * Steal the socket from userland so that it doesn't close * unexpectedly. */ if (so->so_type == SOCK_DGRAM) xprt = svc_dg_create(nfsrvd_pool, so, 0, 0); else xprt = svc_vc_create(nfsrvd_pool, so, 0, 0); if (xprt) { fp->f_ops = &badfileops; fp->f_data = NULL; xprt->xp_sockref = ++sockref; if (nfs_minvers == NFS_VER2) svc_reg(xprt, NFS_PROG, NFS_VER2, nfssvc_program, NULL); if (nfs_minvers <= NFS_VER3 && nfs_maxvers >= NFS_VER3) svc_reg(xprt, NFS_PROG, NFS_VER3, nfssvc_program, NULL); if (nfs_maxvers >= NFS_VER4) svc_reg(xprt, NFS_PROG, NFS_VER4, nfssvc_program, NULL); if (so->so_type == SOCK_STREAM) svc_loss_reg(xprt, nfssvc_loss); SVC_RELEASE(xprt); } out: NFSEXITCODE(error); return (error); }
static int ddp_attach(struct socket *so, int proto, struct thread *td) { int error = 0; KASSERT(sotoddpcb(so) == NULL, ("ddp_attach: ddp != NULL")); /* * Allocate socket buffer space first so that it's present * before first use. */ error = soreserve(so, ddp_sendspace, ddp_recvspace); if (error) return (error); DDP_LIST_XLOCK(); error = at_pcballoc(so); DDP_LIST_XUNLOCK(); return (error); }
static int sco_attach(struct socket *so, int proto) { int error; KASSERT(so->so_pcb == NULL); if (so->so_lock == NULL) { mutex_obj_hold(bt_lock); so->so_lock = bt_lock; solock(so); } KASSERT(solocked(so)); error = soreserve(so, sco_sendspace, sco_recvspace); if (error) { return error; } return sco_attach_pcb((struct sco_pcb **)&so->so_pcb, &sco_proto, so); }
/* * Attach TCP protocol to socket, allocating * internet protocol control block, tcp control block, * bufer space, and entering LISTEN state if to accept connections. */ static int tcp_attach(struct socket *so) { struct tcpcb *tp; struct inpcb *inp; int error; if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { error = soreserve(so, tcp_sendspace, tcp_recvspace); if (error) return (error); } so->so_rcv.sb_flags |= SB_AUTOSIZE; so->so_snd.sb_flags |= SB_AUTOSIZE; INP_INFO_WLOCK(&V_tcbinfo); error = in_pcballoc(so, &V_tcbinfo); if (error) { INP_INFO_WUNLOCK(&V_tcbinfo); return (error); } inp = sotoinpcb(so); #ifdef INET6 if (inp->inp_vflag & INP_IPV6PROTO) { inp->inp_vflag |= INP_IPV6; inp->in6p_hops = -1; /* use kernel default */ } else #endif inp->inp_vflag |= INP_IPV4; tp = tcp_newtcpcb(inp); if (tp == NULL) { in_pcbdetach(inp); in_pcbfree(inp); INP_INFO_WUNLOCK(&V_tcbinfo); return (ENOBUFS); } tp->t_state = TCPS_CLOSED; INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&V_tcbinfo); return (0); }
/* * Allocate a control block and a nominal amount * of buffer space for the socket. */ int raw_attach(struct socket *so, int proto) { struct rawcb *rp = sotorawcb(so); int error; /* * It is assumed that raw_attach is called * after space has been allocated for the * rawcb. */ if (rp == 0) return (ENOBUFS); if ((error = soreserve(so, raw_sendspace, raw_recvspace)) != 0) return (error); rp->rcb_socket = so; rp->rcb_proto.sp_family = so->so_proto->pr_domain->dom_family; rp->rcb_proto.sp_protocol = proto; LIST_INSERT_HEAD(&rawcb, rp, rcb_list); return (0); }
static int ddp_attach(struct socket *so, int proto, struct proc *p) { struct ddpcb *ddp; int error = 0; int s; ddp = sotoddpcb( so ); if ( ddp != NULL ) { return( EINVAL); } s = splnet(); error = at_pcballoc( so ); splx(s); if (error) { return (error); } return (soreserve( so, ddp_sendspace, ddp_recvspace )); }
/* * Set up a socket protocol control block. * This code is shared between control and data sockets. */ static int ng_attach_common(struct socket *so, int type) { struct ngpcb *pcbp; int error; /* Standard socket setup stuff. */ error = soreserve(so, ngpdg_sendspace, ngpdg_recvspace, NULL); if (error) return (error); /* Allocate the pcb. */ pcbp = kmalloc(sizeof(struct ngpcb), M_PCB, M_WAITOK | M_ZERO); pcbp->type = type; /* Link the pcb and the socket. */ so->so_pcb = (caddr_t)pcbp; pcbp->ng_socket = so; return (0); }
static void udp6_attach(netmsg_t msg) { struct socket *so = msg->attach.base.nm_so; struct pru_attach_info *ai = msg->attach.nm_ai; struct inpcb *inp; int error; inp = so->so_pcb; if (inp != NULL) { error = EINVAL; goto out; } if (so->so_snd.ssb_hiwat == 0 || so->so_rcv.ssb_hiwat == 0) { error = soreserve(so, udp_sendspace, udp_recvspace, ai->sb_rlimit); if (error) goto out; } error = in_pcballoc(so, &udbinfo[0]); if (error) goto out; inp = (struct inpcb *)so->so_pcb; inp->in6p_hops = -1; /* use kernel default */ inp->in6p_cksum = -1; /* just to be sure */ /* * XXX: ugly!! * IPv4 TTL initialization is necessary for an IPv6 socket as well, * because the socket may be bound to an IPv6 wildcard address, * which may match an IPv4-mapped IPv6 address. */ inp->inp_ip_ttl = ip_defttl; error = 0; out: lwkt_replymsg(&msg->attach.base.lmsg, error); }
int ddp_pru_attach(struct socket *so, int proto, struct proc *p) { int s, error = 0; at_ddp_t *ddp = NULL; struct atpcb *pcb = (struct atpcb *)((so)->so_pcb); error = soreserve(so, ddp_sendspace, ddp_recvspace); if (error != 0) return error; s = splnet(); error = at_pcballoc(so, &ddp_head); splx(s); if (error) return error; pcb = (struct atpcb *)((so)->so_pcb); pcb->pid = current_proc()->p_pid; pcb->ddptype = (u_char) proto; /* set in socreate() */ pcb->proto = ATPROTO_DDP; return error; }
static int udp_attach(struct socket *so, int proto, struct thread *td) { struct inpcb *inp; struct inpcbinfo *pcbinfo; int error; pcbinfo = get_inpcbinfo(so->so_proto->pr_protocol); inp = sotoinpcb(so); KASSERT(inp == NULL, ("udp_attach: inp != NULL")); error = soreserve(so, udp_sendspace, udp_recvspace); if (error) return (error); INP_INFO_WLOCK(pcbinfo); error = in_pcballoc(so, pcbinfo); if (error) { INP_INFO_WUNLOCK(pcbinfo); return (error); } inp = sotoinpcb(so); inp->inp_vflag |= INP_IPV4; inp->inp_ip_ttl = V_ip_defttl; error = udp_newudpcb(inp); if (error) { in_pcbdetach(inp); in_pcbfree(inp); INP_INFO_WUNLOCK(pcbinfo); return (error); } INP_WUNLOCK(inp); INP_INFO_WUNLOCK(pcbinfo); return (0); }
/* ----------------------------------------------------------------------------- Called by socket layer when a new socket is created Should create all the structures and prepare for L2TP dialog ----------------------------------------------------------------------------- */ int l2tp_attach (struct socket *so, int proto, struct proc *p) { int error; //IOLog("l2tp_attach, so = %p, dom_ref = %d\n", so, so->so_proto->pr_domain->dom_refs); if (so->so_pcb) return EINVAL; if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { error = soreserve(so, 8192, 8192); if (error) return error; } // call l2tp init with the rfc specific structure lck_mtx_lock(ppp_domain_mutex); if (l2tp_rfc_new_client(so, (void**)&(so->so_pcb), l2tp_input, l2tp_event)) { lck_mtx_unlock(ppp_domain_mutex); return ENOMEM; } lck_mtx_unlock(ppp_domain_mutex); return 0; }