malloc(9) or pool_get(9).
Pass down a wait flag to pru_attach(). During syscall socket(2)
it is ok to wait, this logic was missing for internet pcb. Pfkey
and route sockets were already waiting.
sonewconn() must not wait when called during TCP 3-way handshake.
This logic has been preserved. Unix domain stream socket connect(2)
can wait until the other side has created the socket to accept.
OK mvs@
-/* $OpenBSD: uipc_socket.c,v 1.289 2022/09/05 14:56:08 bluhm Exp $ */
+/* $OpenBSD: uipc_socket.c,v 1.290 2022/10/03 16:43:52 bluhm Exp $ */
/* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */
/*
}
struct socket *
-soalloc(int prflags)
+soalloc(int wait)
{
struct socket *so;
- so = pool_get(&socket_pool, prflags);
+ so = pool_get(&socket_pool, (wait == M_WAIT ? PR_WAITOK : PR_NOWAIT) |
+ PR_ZERO);
if (so == NULL)
return (NULL);
rw_init_flags(&so->so_lock, "solock", RWL_DUPOK);
return (EPROTONOSUPPORT);
if (prp->pr_type != type)
return (EPROTOTYPE);
- so = soalloc(PR_WAITOK | PR_ZERO);
+ so = soalloc(M_WAIT);
klist_init(&so->so_rcv.sb_sel.si_note, &socket_klistops, so);
klist_init(&so->so_snd.sb_sel.si_note, &socket_klistops, so);
sigio_init(&so->so_sigio);
so->so_rcv.sb_timeo_nsecs = INFSLP;
solock(so);
- error = pru_attach(so, proto);
+ error = pru_attach(so, proto, M_WAIT);
if (error) {
so->so_state |= SS_NOFDREF;
/* sofree() calls sounlock(). */
-/* $OpenBSD: uipc_socket2.c,v 1.128 2022/09/05 14:56:09 bluhm Exp $ */
+/* $OpenBSD: uipc_socket2.c,v 1.129 2022/10/03 16:43:52 bluhm Exp $ */
/* $NetBSD: uipc_socket2.c,v 1.11 1996/02/04 02:17:55 christos Exp $ */
/*
* Connstatus may be 0 or SS_ISCONNECTED.
*/
struct socket *
-sonewconn(struct socket *head, int connstatus)
+sonewconn(struct socket *head, int connstatus, int wait)
{
struct socket *so;
int persocket = solock_persocket(head);
return (NULL);
if (head->so_qlen + head->so_q0len > head->so_qlimit * 3)
return (NULL);
- so = soalloc(PR_NOWAIT | PR_ZERO);
+ so = soalloc(wait);
if (so == NULL)
return (NULL);
so->so_type = head->so_type;
sounlock(head);
}
- error = pru_attach(so, 0);
+ error = pru_attach(so, 0, wait);
if (persocket) {
sounlock(so);
-/* $OpenBSD: uipc_usrreq.c,v 1.189 2022/09/20 10:10:11 mvs Exp $ */
+/* $OpenBSD: uipc_usrreq.c,v 1.190 2022/10/03 16:43:52 bluhm Exp $ */
/* $NetBSD: uipc_usrreq.c,v 1.18 1996/02/09 19:00:50 christos Exp $ */
/*
};
int
-uipc_attach(struct socket *so, int proto)
+uipc_attach(struct socket *so, int proto, int wait)
{
struct unpcb *unp;
int error;
if (error)
return (error);
}
- unp = pool_get(&unpcb_pool, PR_NOWAIT|PR_ZERO);
+ unp = pool_get(&unpcb_pool, (wait == M_WAIT ? PR_WAITOK : PR_NOWAIT) |
+ PR_ZERO);
if (unp == NULL)
return (ENOBUFS);
refcnt_init(&unp->unp_refcnt);
solock(so2);
if ((so2->so_options & SO_ACCEPTCONN) == 0 ||
- (so3 = sonewconn(so2, 0)) == NULL) {
+ (so3 = sonewconn(so2, 0, M_WAIT)) == NULL) {
error = ECONNREFUSED;
}
-/* $OpenBSD: pfkeyv2.c,v 1.252 2022/09/03 22:43:38 mvs Exp $ */
+/* $OpenBSD: pfkeyv2.c,v 1.253 2022/10/03 16:43:52 bluhm Exp $ */
/*
* @(#)COPYRIGHT 1.1 (NRL) 17 January 1995
void pfkey_init(void);
-int pfkeyv2_attach(struct socket *, int);
+int pfkeyv2_attach(struct socket *, int, int);
int pfkeyv2_detach(struct socket *);
int pfkeyv2_disconnect(struct socket *);
int pfkeyv2_shutdown(struct socket *);
* Attach a new PF_KEYv2 socket.
*/
int
-pfkeyv2_attach(struct socket *so, int proto)
+pfkeyv2_attach(struct socket *so, int proto, int wait)
{
struct pkpcb *kp;
int error;
if (error)
return (error);
- kp = pool_get(&pkpcb_pool, PR_WAITOK|PR_ZERO);
+ kp = pool_get(&pkpcb_pool, (wait == M_WAIT ? PR_WAITOK : PR_NOWAIT) |
+ PR_ZERO);
+ if (kp == NULL)
+ return (ENOBUFS);
so->so_pcb = kp;
refcnt_init(&kp->kcb_refcnt);
kp->kcb_socket = so;
-/* $OpenBSD: rtsock.c,v 1.356 2022/09/13 09:05:47 mvs Exp $ */
+/* $OpenBSD: rtsock.c,v 1.357 2022/10/03 16:43:52 bluhm Exp $ */
/* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */
/*
void rcb_unref(void *, void *);
int route_output(struct mbuf *, struct socket *);
int route_ctloutput(int, struct socket *, int, int, struct mbuf *);
-int route_attach(struct socket *, int);
+int route_attach(struct socket *, int, int);
int route_detach(struct socket *);
int route_disconnect(struct socket *);
int route_shutdown(struct socket *);
}
int
-route_attach(struct socket *so, int proto)
+route_attach(struct socket *so, int proto, int wait)
{
struct rtpcb *rop;
int error;
* code does not care about the additional fields
* and works directly on the raw socket.
*/
- rop = pool_get(&rtpcb_pool, PR_WAITOK|PR_ZERO);
+ rop = pool_get(&rtpcb_pool, (wait == M_WAIT ? PR_WAITOK : PR_NOWAIT) |
+ PR_ZERO);
+ if (rop == NULL)
+ return (ENOBUFS);
so->so_pcb = rop;
/* Init the timeout structure */
timeout_set_proc(&rop->rop_timeout, rtm_senddesync_timer, so);
-/* $OpenBSD: in_pcb.c,v 1.275 2022/09/03 22:43:38 mvs Exp $ */
+/* $OpenBSD: in_pcb.c,v 1.276 2022/10/03 16:43:52 bluhm Exp $ */
/* $NetBSD: in_pcb.c,v 1.25 1996/02/13 23:41:53 christos Exp $ */
/*
}
int
-in_pcballoc(struct socket *so, struct inpcbtable *table)
+in_pcballoc(struct socket *so, struct inpcbtable *table, int wait)
{
struct inpcb *inp;
- inp = pool_get(&inpcb_pool, PR_NOWAIT|PR_ZERO);
+ inp = pool_get(&inpcb_pool, (wait == M_WAIT ? PR_WAITOK : PR_NOWAIT) |
+ PR_ZERO);
if (inp == NULL)
return (ENOBUFS);
inp->inp_table = table;
-/* $OpenBSD: in_pcb.h,v 1.134 2022/09/03 22:43:38 mvs Exp $ */
+/* $OpenBSD: in_pcb.h,v 1.135 2022/10/03 16:43:52 bluhm Exp $ */
/* $NetBSD: in_pcb.h,v 1.14 1996/02/13 23:42:00 christos Exp $ */
/*
void in_init(void);
void in_losing(struct inpcb *);
-int in_pcballoc(struct socket *, struct inpcbtable *);
+int in_pcballoc(struct socket *, struct inpcbtable *, int);
int in_pcbbind(struct inpcb *, struct mbuf *, struct proc *);
int in_pcbaddrisavail(struct inpcb *, struct sockaddr_in *, int,
struct proc *);
-/* $OpenBSD: ip_divert.c,v 1.87 2022/09/05 14:56:09 bluhm Exp $ */
+/* $OpenBSD: ip_divert.c,v 1.88 2022/10/03 16:43:52 bluhm Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
}
int
-divert_attach(struct socket *so, int proto)
+divert_attach(struct socket *so, int proto, int wait)
{
int error;
if ((so->so_state & SS_PRIV) == 0)
return EACCES;
- error = in_pcballoc(so, &divbtable);
+ error = in_pcballoc(so, &divbtable, wait);
if (error)
return error;
-/* $OpenBSD: ip_divert.h,v 1.22 2022/09/05 14:56:09 bluhm Exp $ */
+/* $OpenBSD: ip_divert.h,v 1.23 2022/10/03 16:43:52 bluhm Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
void divert_init(void);
void divert_packet(struct mbuf *, int, u_int16_t);
int divert_sysctl(int *, u_int, void *, size_t *, void *, size_t);
-int divert_attach(struct socket *, int);
+int divert_attach(struct socket *, int, int);
int divert_detach(struct socket *);
void divert_lock(struct socket *);
void divert_unlock(struct socket *);
-/* $OpenBSD: ip_var.h,v 1.105 2022/09/13 09:05:02 mvs Exp $ */
+/* $OpenBSD: ip_var.h,v 1.106 2022/10/03 16:43:52 bluhm Exp $ */
/* $NetBSD: ip_var.h,v 1.16 1996/02/13 23:43:20 christos Exp $ */
/*
int rip_input(struct mbuf **, int *, int, int);
int rip_output(struct mbuf *, struct socket *, struct sockaddr *,
struct mbuf *);
-int rip_attach(struct socket *, int);
+int rip_attach(struct socket *, int, int);
int rip_detach(struct socket *);
void rip_lock(struct socket *);
void rip_unlock(struct socket *);
-/* $OpenBSD: raw_ip.c,v 1.148 2022/09/13 09:05:02 mvs Exp $ */
+/* $OpenBSD: raw_ip.c,v 1.149 2022/10/03 16:43:52 bluhm Exp $ */
/* $NetBSD: raw_ip.c,v 1.25 1996/02/18 18:58:33 christos Exp $ */
/*
u_long rip_recvspace = RIPRCVQ;
int
-rip_attach(struct socket *so, int proto)
+rip_attach(struct socket *so, int proto, int wait)
{
struct inpcb *inp;
int error;
if ((error = soreserve(so, rip_sendspace, rip_recvspace)))
return error;
NET_ASSERT_LOCKED();
- if ((error = in_pcballoc(so, &rawcbtable)))
+ if ((error = in_pcballoc(so, &rawcbtable, wait)))
return error;
inp = sotoinpcb(so);
inp->inp_ip.ip_p = proto;
-/* $OpenBSD: tcp_input.c,v 1.380 2022/09/03 19:22:19 bluhm Exp $ */
+/* $OpenBSD: tcp_input.c,v 1.381 2022/10/03 16:43:52 bluhm Exp $ */
/* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */
/*
* the connection, abort it.
*/
oso = so;
- so = sonewconn(so, SS_ISCONNECTED);
+ so = sonewconn(so, SS_ISCONNECTED, M_DONTWAIT);
if (so == NULL)
goto resetandabort;
-/* $OpenBSD: tcp_subr.c,v 1.188 2022/09/03 22:11:09 bluhm Exp $ */
+/* $OpenBSD: tcp_subr.c,v 1.189 2022/10/03 16:43:52 bluhm Exp $ */
/* $NetBSD: tcp_subr.c,v 1.22 1996/02/13 23:44:00 christos Exp $ */
/*
* protocol control block.
*/
struct tcpcb *
-tcp_newtcpcb(struct inpcb *inp)
+tcp_newtcpcb(struct inpcb *inp, int wait)
{
struct tcpcb *tp;
int i;
- tp = pool_get(&tcpcb_pool, PR_NOWAIT|PR_ZERO);
+ tp = pool_get(&tcpcb_pool, (wait == M_WAIT ? PR_WAITOK : PR_NOWAIT) |
+ PR_ZERO);
if (tp == NULL)
return (NULL);
TAILQ_INIT(&tp->t_segq);
-/* $OpenBSD: tcp_usrreq.c,v 1.208 2022/09/13 09:05:47 mvs Exp $ */
+/* $OpenBSD: tcp_usrreq.c,v 1.209 2022/10/03 16:43:52 bluhm Exp $ */
/* $NetBSD: tcp_usrreq.c,v 1.20 1996/02/13 23:44:16 christos Exp $ */
/*
* buffer space, and entering LISTEN state to accept connections.
*/
int
-tcp_attach(struct socket *so, int proto)
+tcp_attach(struct socket *so, int proto, int wait)
{
struct tcpcb *tp;
struct inpcb *inp;
}
NET_ASSERT_LOCKED();
- error = in_pcballoc(so, &tcbtable);
+ error = in_pcballoc(so, &tcbtable, wait);
if (error)
return (error);
inp = sotoinpcb(so);
- tp = tcp_newtcpcb(inp);
+ tp = tcp_newtcpcb(inp, wait);
if (tp == NULL) {
unsigned int nofd = so->so_state & SS_NOFDREF; /* XXX */
-/* $OpenBSD: tcp_var.h,v 1.158 2022/09/13 09:05:47 mvs Exp $ */
+/* $OpenBSD: tcp_var.h,v 1.159 2022/10/03 16:43:52 bluhm Exp $ */
/* $NetBSD: tcp_var.h,v 1.17 1996/02/13 23:44:24 christos Exp $ */
/*
void tcp6_mtudisc_callback(struct sockaddr_in6 *, u_int);
#endif
struct tcpcb *
- tcp_newtcpcb(struct inpcb *);
+ tcp_newtcpcb(struct inpcb *, int);
void tcp_notify(struct inpcb *, int);
int tcp_output(struct tcpcb *);
void tcp_pulloutofband(struct socket *, u_int, struct mbuf *, int);
struct tcpcb *
tcp_usrclosed(struct tcpcb *);
int tcp_sysctl(int *, u_int, void *, size_t *, void *, size_t);
-int tcp_attach(struct socket *, int);
+int tcp_attach(struct socket *, int, int);
int tcp_detach(struct socket *);
int tcp_bind(struct socket *, struct mbuf *, struct proc *);
int tcp_listen(struct socket *);
-/* $OpenBSD: udp_usrreq.c,v 1.302 2022/09/05 14:56:09 bluhm Exp $ */
+/* $OpenBSD: udp_usrreq.c,v 1.303 2022/10/03 16:43:52 bluhm Exp $ */
/* $NetBSD: udp_usrreq.c,v 1.28 1996/03/16 23:54:03 christos Exp $ */
/*
}
int
-udp_attach(struct socket *so, int proto)
+udp_attach(struct socket *so, int proto, int wait)
{
int error;
return error;
NET_ASSERT_LOCKED();
- if ((error = in_pcballoc(so, &udbtable)))
+ if ((error = in_pcballoc(so, &udbtable, wait)))
return error;
#ifdef INET6
if (sotoinpcb(so)->inp_flags & INP_IPV6)
-/* $OpenBSD: udp_var.h,v 1.47 2022/09/05 14:56:09 bluhm Exp $ */
+/* $OpenBSD: udp_var.h,v 1.48 2022/10/03 16:43:52 bluhm Exp $ */
/* $NetBSD: udp_var.h,v 1.12 1996/02/13 23:44:41 christos Exp $ */
/*
struct mbuf *);
#endif /* INET6 */
int udp_sysctl(int *, u_int, void *, size_t *, void *, size_t);
-int udp_attach(struct socket *, int);
+int udp_attach(struct socket *, int, int);
int udp_detach(struct socket *);
void udp_lock(struct socket *);
void udp_unlock(struct socket *);
-/* $OpenBSD: ip6_divert.c,v 1.86 2022/09/05 14:56:09 bluhm Exp $ */
+/* $OpenBSD: ip6_divert.c,v 1.87 2022/10/03 16:43:52 bluhm Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
}
int
-divert6_attach(struct socket *so, int proto)
+divert6_attach(struct socket *so, int proto, int wait)
{
int error;
if ((so->so_state & SS_PRIV) == 0)
return EACCES;
- error = in_pcballoc(so, &divb6table);
+ error = in_pcballoc(so, &divb6table, wait);
if (error)
return (error);
-/* $OpenBSD: ip6_divert.h,v 1.20 2022/09/05 14:56:09 bluhm Exp $ */
+/* $OpenBSD: ip6_divert.h,v 1.21 2022/10/03 16:43:52 bluhm Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
void divert6_init(void);
void divert6_packet(struct mbuf *, int, u_int16_t);
int divert6_sysctl(int *, u_int, void *, size_t *, void *, size_t);
-int divert6_attach(struct socket *, int);
+int divert6_attach(struct socket *, int, int);
int divert6_detach(struct socket *);
void divert6_lock(struct socket *);
void divert6_unlock(struct socket *);
-/* $OpenBSD: ip6_var.h,v 1.103 2022/09/13 09:05:02 mvs Exp $ */
+/* $OpenBSD: ip6_var.h,v 1.104 2022/10/03 16:43:52 bluhm Exp $ */
/* $KAME: ip6_var.h,v 1.33 2000/06/11 14:59:20 jinmei Exp $ */
/*
int rip6_ctloutput(int, struct socket *, int, int, struct mbuf *);
int rip6_output(struct mbuf *, struct socket *, struct sockaddr *,
struct mbuf *);
-int rip6_attach(struct socket *, int);
+int rip6_attach(struct socket *, int, int);
int rip6_detach(struct socket *);
void rip6_lock(struct socket *);
void rip6_unlock(struct socket *);
-/* $OpenBSD: raw_ip6.c,v 1.169 2022/09/13 09:05:02 mvs Exp $ */
+/* $OpenBSD: raw_ip6.c,v 1.170 2022/10/03 16:43:52 bluhm Exp $ */
/* $KAME: raw_ip6.c,v 1.69 2001/03/04 15:55:44 itojun Exp $ */
/*
extern u_long rip6_recvspace;
int
-rip6_attach(struct socket *so, int proto)
+rip6_attach(struct socket *so, int proto, int wait)
{
struct inpcb *in6p;
int error;
if ((error = soreserve(so, rip6_sendspace, rip6_recvspace)))
return error;
NET_ASSERT_LOCKED();
- if ((error = in_pcballoc(so, &rawin6pcbtable)))
+ if ((error = in_pcballoc(so, &rawin6pcbtable, wait)))
return error;
in6p = sotoinpcb(so);
in6p->inp_ipv6.ip6_nxt = proto;
in6p->inp_cksum6 = -1;
- in6p->inp_icmp6filt = malloc(sizeof(struct icmp6_filter),
- M_PCB, M_NOWAIT);
+ in6p->inp_icmp6filt = malloc(sizeof(struct icmp6_filter), M_PCB,
+ wait == M_WAIT ? M_WAITOK : M_NOWAIT);
if (in6p->inp_icmp6filt == NULL) {
in_pcbdetach(in6p);
return ENOMEM;
-/* $OpenBSD: protosw.h,v 1.56 2022/09/13 09:05:47 mvs Exp $ */
+/* $OpenBSD: protosw.h,v 1.57 2022/10/03 16:43:52 bluhm Exp $ */
/* $NetBSD: protosw.h,v 1.10 1996/04/09 20:55:32 cgd Exp $ */
/*-
struct ifnet;
struct pr_usrreqs {
- int (*pru_attach)(struct socket *, int);
+ int (*pru_attach)(struct socket *, int, int);
int (*pru_detach)(struct socket *);
void (*pru_lock)(struct socket *);
void (*pru_unlock)(struct socket *);
#endif /* INET6 */
static inline int
-pru_attach(struct socket *so, int proto)
+pru_attach(struct socket *so, int proto, int wait)
{
- return (*so->so_proto->pr_usrreqs->pru_attach)(so, proto);
+ return (*so->so_proto->pr_usrreqs->pru_attach)(so, proto, wait);
}
static inline int
-/* $OpenBSD: socketvar.h,v 1.110 2022/09/05 14:56:09 bluhm Exp $ */
+/* $OpenBSD: socketvar.h,v 1.111 2022/10/03 16:43:52 bluhm Exp $ */
/* $NetBSD: socketvar.h,v 1.18 1996/02/09 18:25:38 christos Exp $ */
/*-
void soisdisconnected(struct socket *);
void soisdisconnecting(struct socket *);
int solisten(struct socket *, int);
-struct socket *sonewconn(struct socket *, int);
+struct socket *sonewconn(struct socket *, int, int);
void soqinsque(struct socket *, struct socket *, int);
int soqremque(struct socket *, int);
int soreceive(struct socket *, struct mbuf **, struct uio *,
-/* $OpenBSD: unpcb.h,v 1.41 2022/09/13 09:05:47 mvs Exp $ */
+/* $OpenBSD: unpcb.h,v 1.42 2022/10/03 16:43:52 bluhm Exp $ */
/* $NetBSD: unpcb.h,v 1.6 1994/06/29 06:46:08 cgd Exp $ */
/*
extern const struct pr_usrreqs uipc_usrreqs;
-int uipc_attach(struct socket *, int);
+int uipc_attach(struct socket *, int, int);
int uipc_detach(struct socket *);
int uipc_bind(struct socket *, struct mbuf *, struct proc *);
int uipc_listen(struct socket *);