mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-13 14:40:22 +00:00
Ensure that 1-to-1 style SCTP sockets can only be connected once.
Allow implicit setup also for 1-to-1 style sockets as described in the latest version of the socket API ID. Approved by: re MFC after: 1 month
This commit is contained in:
parent
7cd72d8565
commit
c55b70cef6
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=225559
@ -12628,14 +12628,10 @@ sctp_lower_sosend(struct socket *so,
|
||||
(inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
|
||||
SCTP_INP_RLOCK(inp);
|
||||
stcb = LIST_FIRST(&inp->sctp_asoc_list);
|
||||
if (stcb == NULL) {
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, ENOTCONN);
|
||||
error = ENOTCONN;
|
||||
goto out_unlocked;
|
||||
if (stcb) {
|
||||
SCTP_TCB_LOCK(stcb);
|
||||
hold_tcblock = 1;
|
||||
}
|
||||
SCTP_TCB_LOCK(stcb);
|
||||
hold_tcblock = 1;
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
} else if (sinfo_assoc_id) {
|
||||
stcb = sctp_findassociation_ep_asocid(inp, sinfo_assoc_id, 0);
|
||||
@ -12700,21 +12696,12 @@ sctp_lower_sosend(struct socket *so,
|
||||
}
|
||||
}
|
||||
if (stcb == NULL) {
|
||||
if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
|
||||
(inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
|
||||
SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, ENOTCONN);
|
||||
error = ENOTCONN;
|
||||
goto out_unlocked;
|
||||
}
|
||||
if (addr == NULL) {
|
||||
SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, ENOENT);
|
||||
error = ENOENT;
|
||||
goto out_unlocked;
|
||||
} else {
|
||||
/*
|
||||
* UDP style, we must go ahead and start the INIT
|
||||
* process
|
||||
*/
|
||||
/* We must go ahead and start the INIT process */
|
||||
uint32_t vrf_id;
|
||||
|
||||
if ((sinfo_flags & SCTP_ABORT) ||
|
||||
@ -12741,6 +12728,14 @@ sctp_lower_sosend(struct socket *so,
|
||||
/* Error is setup for us in the call */
|
||||
goto out_unlocked;
|
||||
}
|
||||
if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) {
|
||||
stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED;
|
||||
/*
|
||||
* Set the connected flag so we can queue
|
||||
* data
|
||||
*/
|
||||
soisconnecting(so);
|
||||
}
|
||||
hold_tcblock = 1;
|
||||
if (create_lock_applied) {
|
||||
SCTP_ASOC_CREATE_UNLOCK(inp);
|
||||
|
@ -4291,6 +4291,16 @@ sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
|
||||
*error = EINVAL;
|
||||
return (NULL);
|
||||
}
|
||||
if ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
|
||||
(inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE)) {
|
||||
if ((inp->sctp_flags & SCTP_PCB_FLAGS_WAS_CONNECTED) ||
|
||||
(inp->sctp_flags & SCTP_PCB_FLAGS_WAS_ABORTED)) {
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
|
||||
*error = EINVAL;
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
SCTPDBG(SCTP_DEBUG_PCB3, "Allocate an association for peer:");
|
||||
#ifdef SCTP_DEBUG
|
||||
if (firstaddr) {
|
||||
|
@ -1541,6 +1541,11 @@ sctp_do_connect_x(struct socket *so, struct sctp_inpcb *inp, void *optval,
|
||||
/* Gak! no memory */
|
||||
goto out_now;
|
||||
}
|
||||
if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) {
|
||||
stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED;
|
||||
/* Set the connected flag so we can queue data */
|
||||
soisconnecting(so);
|
||||
}
|
||||
SCTP_SET_STATE(&stcb->asoc, SCTP_STATE_COOKIE_WAIT);
|
||||
/* move to second address */
|
||||
switch (sa->sa_family) {
|
||||
@ -5772,15 +5777,6 @@ sctp_connect(struct socket *so, struct sockaddr *addr, struct thread *p)
|
||||
if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) {
|
||||
stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED;
|
||||
/* Set the connected flag so we can queue data */
|
||||
SOCKBUF_LOCK(&so->so_rcv);
|
||||
so->so_rcv.sb_state &= ~SBS_CANTRCVMORE;
|
||||
SOCKBUF_UNLOCK(&so->so_rcv);
|
||||
SOCKBUF_LOCK(&so->so_snd);
|
||||
so->so_snd.sb_state &= ~SBS_CANTSENDMORE;
|
||||
SOCKBUF_UNLOCK(&so->so_snd);
|
||||
SOCK_LOCK(so);
|
||||
so->so_state &= ~SS_ISDISCONNECTING;
|
||||
SOCK_UNLOCK(so);
|
||||
soisconnecting(so);
|
||||
}
|
||||
SCTP_SET_STATE(&stcb->asoc, SCTP_STATE_COOKIE_WAIT);
|
||||
|
@ -3622,10 +3622,14 @@ sctp_abort_notification(struct sctp_tcb *stcb, int error, int so_locked
|
||||
#endif
|
||||
)
|
||||
{
|
||||
|
||||
if (stcb == NULL) {
|
||||
return;
|
||||
}
|
||||
if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
|
||||
((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
|
||||
(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED))) {
|
||||
stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_WAS_ABORTED;
|
||||
}
|
||||
if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
|
||||
(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
|
||||
(stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET)) {
|
||||
@ -3633,11 +3637,6 @@ sctp_abort_notification(struct sctp_tcb *stcb, int error, int so_locked
|
||||
}
|
||||
/* Tell them we lost the asoc */
|
||||
sctp_report_all_outbound(stcb, 1, so_locked);
|
||||
if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
|
||||
((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
|
||||
(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED))) {
|
||||
stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_WAS_ABORTED;
|
||||
}
|
||||
sctp_ulp_notify(SCTP_NOTIFY_ASSOC_ABORTED, stcb, error, NULL, so_locked);
|
||||
}
|
||||
|
||||
@ -5098,17 +5097,6 @@ sctp_sorecvmsg(struct socket *so,
|
||||
*/
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, ECONNRESET);
|
||||
error = ECONNRESET;
|
||||
/*
|
||||
* You get this once if you are
|
||||
* active open side
|
||||
*/
|
||||
if (!(inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
|
||||
/*
|
||||
* Remove flag if on the
|
||||
* active open side
|
||||
*/
|
||||
inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAS_ABORTED;
|
||||
}
|
||||
}
|
||||
so->so_state &= ~(SS_ISCONNECTING |
|
||||
SS_ISDISCONNECTING |
|
||||
@ -5118,8 +5106,6 @@ sctp_sorecvmsg(struct socket *so,
|
||||
if ((inp->sctp_flags & SCTP_PCB_FLAGS_WAS_CONNECTED) == 0) {
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, ENOTCONN);
|
||||
error = ENOTCONN;
|
||||
} else {
|
||||
inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAS_CONNECTED;
|
||||
}
|
||||
}
|
||||
goto out;
|
||||
@ -5152,18 +5138,6 @@ sctp_sorecvmsg(struct socket *so,
|
||||
*/
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, ECONNRESET);
|
||||
error = ECONNRESET;
|
||||
/*
|
||||
* You get this once if you
|
||||
* are active open side
|
||||
*/
|
||||
if (!(inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
|
||||
/*
|
||||
* Remove flag if on
|
||||
* the active open
|
||||
* side
|
||||
*/
|
||||
inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAS_ABORTED;
|
||||
}
|
||||
}
|
||||
so->so_state &= ~(SS_ISCONNECTING |
|
||||
SS_ISDISCONNECTING |
|
||||
@ -5173,8 +5147,6 @@ sctp_sorecvmsg(struct socket *so,
|
||||
if ((inp->sctp_flags & SCTP_PCB_FLAGS_WAS_CONNECTED) == 0) {
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, ENOTCONN);
|
||||
error = ENOTCONN;
|
||||
} else {
|
||||
inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAS_CONNECTED;
|
||||
}
|
||||
}
|
||||
goto out;
|
||||
|
Loading…
Reference in New Issue
Block a user