Fix a bug which incorrectly allowed two listening SCTP sockets on

the same port bound to the wildcard address.

MFC after: 3 days
This commit is contained in:
Michael Tuexen 2014-06-20 20:17:39 +00:00
parent e876f6d052
commit 2f4c57fbe9
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=267688

View File

@ -6098,30 +6098,29 @@ sctp_listen(struct socket *so, int backlog, struct thread *p)
if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE)) {
/* See if we have a listener */
struct sctp_inpcb *tinp;
union sctp_sockstore store, *sp;
union sctp_sockstore store;
sp = &store;
if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) {
/* not bound all */
struct sctp_laddr *laddr;
LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
memcpy(&store, &laddr->ifa->address, sizeof(store));
switch (sp->sa.sa_family) {
switch (store.sa.sa_family) {
#ifdef INET
case AF_INET:
sp->sin.sin_port = inp->sctp_lport;
store.sin.sin_port = inp->sctp_lport;
break;
#endif
#ifdef INET6
case AF_INET6:
sp->sin6.sin6_port = inp->sctp_lport;
store.sin6.sin6_port = inp->sctp_lport;
break;
#endif
default:
break;
}
tinp = sctp_pcb_findep(&sp->sa, 0, 0, inp->def_vrf_id);
tinp = sctp_pcb_findep(&store.sa, 0, 0, inp->def_vrf_id);
if (tinp && (tinp != inp) &&
((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) == 0) &&
((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
@ -6139,20 +6138,6 @@ sctp_listen(struct socket *so, int backlog, struct thread *p)
} else {
/* Setup a local addr bound all */
memset(&store, 0, sizeof(store));
switch (sp->sa.sa_family) {
#ifdef INET
case AF_INET:
store.sin.sin_port = inp->sctp_lport;
break;
#endif
#ifdef INET6
case AF_INET6:
sp->sin6.sin6_port = inp->sctp_lport;
break;
#endif
default:
break;
}
#ifdef INET6
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
store.sa.sa_family = AF_INET6;
@ -6165,7 +6150,21 @@ sctp_listen(struct socket *so, int backlog, struct thread *p)
store.sa.sa_len = sizeof(struct sockaddr_in);
}
#endif
tinp = sctp_pcb_findep(&sp->sa, 0, 0, inp->def_vrf_id);
switch (store.sa.sa_family) {
#ifdef INET
case AF_INET:
store.sin.sin_port = inp->sctp_lport;
break;
#endif
#ifdef INET6
case AF_INET6:
store.sin6.sin6_port = inp->sctp_lport;
break;
#endif
default:
break;
}
tinp = sctp_pcb_findep(&store.sa, 0, 0, inp->def_vrf_id);
if (tinp && (tinp != inp) &&
((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) == 0) &&
((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&