diff options
Diffstat (limited to 'net/sctp/socket.c')
-rw-r--r-- | net/sctp/socket.c | 40 |
1 files changed, 30 insertions, 10 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 2fc0a92caa78..9f1a908776de 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -972,6 +972,7 @@ static int __sctp_connect(struct sock* sk, | |||
972 | int walk_size = 0; | 972 | int walk_size = 0; |
973 | union sctp_addr *sa_addr; | 973 | union sctp_addr *sa_addr; |
974 | void *addr_buf; | 974 | void *addr_buf; |
975 | unsigned short port; | ||
975 | 976 | ||
976 | sp = sctp_sk(sk); | 977 | sp = sctp_sk(sk); |
977 | ep = sp->ep; | 978 | ep = sp->ep; |
@@ -992,6 +993,7 @@ static int __sctp_connect(struct sock* sk, | |||
992 | while (walk_size < addrs_size) { | 993 | while (walk_size < addrs_size) { |
993 | sa_addr = (union sctp_addr *)addr_buf; | 994 | sa_addr = (union sctp_addr *)addr_buf; |
994 | af = sctp_get_af_specific(sa_addr->sa.sa_family); | 995 | af = sctp_get_af_specific(sa_addr->sa.sa_family); |
996 | port = ntohs(sa_addr->v4.sin_port); | ||
995 | 997 | ||
996 | /* If the address family is not supported or if this address | 998 | /* If the address family is not supported or if this address |
997 | * causes the address buffer to overflow return EINVAL. | 999 | * causes the address buffer to overflow return EINVAL. |
@@ -1005,6 +1007,12 @@ static int __sctp_connect(struct sock* sk, | |||
1005 | if (err) | 1007 | if (err) |
1006 | goto out_free; | 1008 | goto out_free; |
1007 | 1009 | ||
1010 | /* Make sure the destination port is correctly set | ||
1011 | * in all addresses. | ||
1012 | */ | ||
1013 | if (asoc && asoc->peer.port && asoc->peer.port != port) | ||
1014 | goto out_free; | ||
1015 | |||
1008 | memcpy(&to, sa_addr, af->sockaddr_len); | 1016 | memcpy(&to, sa_addr, af->sockaddr_len); |
1009 | 1017 | ||
1010 | /* Check if there already is a matching association on the | 1018 | /* Check if there already is a matching association on the |
@@ -5012,7 +5020,8 @@ pp_found: | |||
5012 | struct hlist_node *node; | 5020 | struct hlist_node *node; |
5013 | 5021 | ||
5014 | SCTP_DEBUG_PRINTK("sctp_get_port() found a possible match\n"); | 5022 | SCTP_DEBUG_PRINTK("sctp_get_port() found a possible match\n"); |
5015 | if (pp->fastreuse && sk->sk_reuse) | 5023 | if (pp->fastreuse && sk->sk_reuse && |
5024 | sk->sk_state != SCTP_SS_LISTENING) | ||
5016 | goto success; | 5025 | goto success; |
5017 | 5026 | ||
5018 | /* Run through the list of sockets bound to the port | 5027 | /* Run through the list of sockets bound to the port |
@@ -5029,7 +5038,8 @@ pp_found: | |||
5029 | struct sctp_endpoint *ep2; | 5038 | struct sctp_endpoint *ep2; |
5030 | ep2 = sctp_sk(sk2)->ep; | 5039 | ep2 = sctp_sk(sk2)->ep; |
5031 | 5040 | ||
5032 | if (reuse && sk2->sk_reuse) | 5041 | if (reuse && sk2->sk_reuse && |
5042 | sk2->sk_state != SCTP_SS_LISTENING) | ||
5033 | continue; | 5043 | continue; |
5034 | 5044 | ||
5035 | if (sctp_bind_addr_match(&ep2->base.bind_addr, addr, | 5045 | if (sctp_bind_addr_match(&ep2->base.bind_addr, addr, |
@@ -5050,9 +5060,13 @@ pp_not_found: | |||
5050 | * if sk->sk_reuse is too (that is, if the caller requested | 5060 | * if sk->sk_reuse is too (that is, if the caller requested |
5051 | * SO_REUSEADDR on this socket -sk-). | 5061 | * SO_REUSEADDR on this socket -sk-). |
5052 | */ | 5062 | */ |
5053 | if (hlist_empty(&pp->owner)) | 5063 | if (hlist_empty(&pp->owner)) { |
5054 | pp->fastreuse = sk->sk_reuse ? 1 : 0; | 5064 | if (sk->sk_reuse && sk->sk_state != SCTP_SS_LISTENING) |
5055 | else if (pp->fastreuse && !sk->sk_reuse) | 5065 | pp->fastreuse = 1; |
5066 | else | ||
5067 | pp->fastreuse = 0; | ||
5068 | } else if (pp->fastreuse && | ||
5069 | (!sk->sk_reuse || sk->sk_state == SCTP_SS_LISTENING)) | ||
5056 | pp->fastreuse = 0; | 5070 | pp->fastreuse = 0; |
5057 | 5071 | ||
5058 | /* We are set, so fill up all the data in the hash table | 5072 | /* We are set, so fill up all the data in the hash table |
@@ -5060,8 +5074,8 @@ pp_not_found: | |||
5060 | * sockets FIXME: Blurry, NPI (ipg). | 5074 | * sockets FIXME: Blurry, NPI (ipg). |
5061 | */ | 5075 | */ |
5062 | success: | 5076 | success: |
5063 | inet_sk(sk)->num = snum; | ||
5064 | if (!sctp_sk(sk)->bind_hash) { | 5077 | if (!sctp_sk(sk)->bind_hash) { |
5078 | inet_sk(sk)->num = snum; | ||
5065 | sk_add_bind_node(sk, &pp->owner); | 5079 | sk_add_bind_node(sk, &pp->owner); |
5066 | sctp_sk(sk)->bind_hash = pp; | 5080 | sctp_sk(sk)->bind_hash = pp; |
5067 | } | 5081 | } |
@@ -5134,12 +5148,16 @@ SCTP_STATIC int sctp_seqpacket_listen(struct sock *sk, int backlog) | |||
5134 | * This is not currently spelled out in the SCTP sockets | 5148 | * This is not currently spelled out in the SCTP sockets |
5135 | * extensions draft, but follows the practice as seen in TCP | 5149 | * extensions draft, but follows the practice as seen in TCP |
5136 | * sockets. | 5150 | * sockets. |
5151 | * | ||
5152 | * Additionally, turn off fastreuse flag since we are not listening | ||
5137 | */ | 5153 | */ |
5154 | sk->sk_state = SCTP_SS_LISTENING; | ||
5138 | if (!ep->base.bind_addr.port) { | 5155 | if (!ep->base.bind_addr.port) { |
5139 | if (sctp_autobind(sk)) | 5156 | if (sctp_autobind(sk)) |
5140 | return -EAGAIN; | 5157 | return -EAGAIN; |
5141 | } | 5158 | } else |
5142 | sk->sk_state = SCTP_SS_LISTENING; | 5159 | sctp_sk(sk)->bind_hash->fastreuse = 0; |
5160 | |||
5143 | sctp_hash_endpoint(ep); | 5161 | sctp_hash_endpoint(ep); |
5144 | return 0; | 5162 | return 0; |
5145 | } | 5163 | } |
@@ -5177,11 +5195,13 @@ SCTP_STATIC int sctp_stream_listen(struct sock *sk, int backlog) | |||
5177 | * extensions draft, but follows the practice as seen in TCP | 5195 | * extensions draft, but follows the practice as seen in TCP |
5178 | * sockets. | 5196 | * sockets. |
5179 | */ | 5197 | */ |
5198 | sk->sk_state = SCTP_SS_LISTENING; | ||
5180 | if (!ep->base.bind_addr.port) { | 5199 | if (!ep->base.bind_addr.port) { |
5181 | if (sctp_autobind(sk)) | 5200 | if (sctp_autobind(sk)) |
5182 | return -EAGAIN; | 5201 | return -EAGAIN; |
5183 | } | 5202 | } else |
5184 | sk->sk_state = SCTP_SS_LISTENING; | 5203 | sctp_sk(sk)->bind_hash->fastreuse = 0; |
5204 | |||
5185 | sk->sk_max_ack_backlog = backlog; | 5205 | sk->sk_max_ack_backlog = backlog; |
5186 | sctp_hash_endpoint(ep); | 5206 | sctp_hash_endpoint(ep); |
5187 | return 0; | 5207 | return 0; |