summaryrefslogtreecommitdiffstats
path: root/sys/netipx
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2006-03-25 15:03:29 +0000
committerrwatson <rwatson@FreeBSD.org>2006-03-25 15:03:29 +0000
commitf594b5f37bad3af3a3ecddfae898048e07a57bc1 (patch)
tree11842e9420815dabd22cfaa6cdb3c5d9c18bdff4 /sys/netipx
parentbb7f7422a3416143c19361a3ec36ba3b2ff33457 (diff)
downloadFreeBSD-src-f594b5f37bad3af3a3ecddfae898048e07a57bc1.zip
FreeBSD-src-f594b5f37bad3af3a3ecddfae898048e07a57bc1.tar.gz
Restructure spx_attach() to properly free memory in the event that one
of its allocations fails. Allocate the ipxp last so as to avoid having to free it if another allocation goes wrong. Normalize retrieval of ipxp and cb from socket in spx_sp_attach(), and add assertions. MFC after: 1 month
Diffstat (limited to 'sys/netipx')
-rw-r--r--sys/netipx/spx_usrreq.c53
1 files changed, 32 insertions, 21 deletions
diff --git a/sys/netipx/spx_usrreq.c b/sys/netipx/spx_usrreq.c
index d2ad220..e562270 100644
--- a/sys/netipx/spx_usrreq.c
+++ b/sys/netipx/spx_usrreq.c
@@ -1344,29 +1344,31 @@ spx_attach(struct socket *so, int proto, struct thread *td)
ipxp = sotoipxpcb(so);
KASSERT(ipxp == NULL, ("spx_attach: ipxp != NULL"));
- IPX_LIST_LOCK();
- error = ipx_pcballoc(so, &ipxpcb_list, td);
- if (error)
- goto spx_attach_end;
if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
error = soreserve(so, (u_long) 3072, (u_long) 3072);
if (error)
- goto spx_attach_end;
+ return (error);
}
- ipxp = sotoipxpcb(so);
MALLOC(cb, struct spxpcb *, sizeof *cb, M_PCB, M_NOWAIT | M_ZERO);
- if (cb == NULL) {
- error = ENOBUFS;
- goto spx_attach_end;
- }
-
+ if (cb == NULL)
+ return (ENOBUFS);
mm = m_getclr(M_DONTWAIT, MT_DATA);
if (mm == NULL) {
FREE(cb, M_PCB);
- error = ENOBUFS;
- goto spx_attach_end;
+ return (ENOBUFS);
+ }
+
+ IPX_LIST_LOCK();
+ error = ipx_pcballoc(so, &ipxpcb_list, td);
+ if (error) {
+ IPX_LIST_UNLOCK();
+ m_free(mm);
+ FREE(cb, M_PCB);
+ return (error);
}
+ ipxp = sotoipxpcb(so);
+
cb->s_ipx = mtod(mm, struct ipx *);
cb->s_state = TCPS_LISTEN;
cb->s_smax = -1;
@@ -1388,7 +1390,6 @@ spx_attach(struct socket *so, int proto, struct thread *td)
((SPXTV_SRTTBASE >> 2) + (SPXTV_SRTTDFLT << 2)) >> 1,
SPXTV_MIN, SPXTV_REXMTMAX);
ipxp->ipxp_pcb = (caddr_t)cb;
-spx_attach_end:
IPX_LIST_UNLOCK();
return (error);
}
@@ -1649,16 +1650,26 @@ spx_shutdown(struct socket *so)
static int
spx_sp_attach(struct socket *so, int proto, struct thread *td)
{
- int error;
struct ipxpcb *ipxp;
+ struct spxpcb *cb;
+ int error;
+
+ KASSERT(so->so_pcb == NULL, ("spx_sp_attach: so_pcb != NULL"));
error = spx_attach(so, proto, td);
- if (error == 0) {
- ipxp = sotoipxpcb(so);
- ((struct spxpcb *)ipxp->ipxp_pcb)->s_flags |=
- (SF_HI | SF_HO | SF_PI);
- }
- return (error);
+ if (error)
+ return (error);
+
+ ipxp = sotoipxpcb(so);
+ KASSERT(ipxp != NULL, ("spx_sp_attach: ipxp == NULL"));
+
+ cb = ipxtospxpcb(ipxp);
+ KASSERT(cb != NULL, ("spx_sp_attach: cb == NULL"));
+
+ IPX_LOCK(ipxp);
+ cb->s_flags |= (SF_HI | SF_HO | SF_PI);
+ IPX_UNLOCK(ipxp);
+ return (0);
}
/*
OpenPOWER on IntegriCloud