|
@@ -2242,14 +2242,17 @@ int sctp_verify_init(const struct sctp_association *asoc,
|
|
* Returns 0 on failure, else success.
|
|
* Returns 0 on failure, else success.
|
|
* FIXME: This is an association method.
|
|
* FIXME: This is an association method.
|
|
*/
|
|
*/
|
|
-int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid,
|
|
|
|
|
|
+int sctp_process_init(struct sctp_association *asoc, struct sctp_chunk *chunk,
|
|
const union sctp_addr *peer_addr,
|
|
const union sctp_addr *peer_addr,
|
|
sctp_init_chunk_t *peer_init, gfp_t gfp)
|
|
sctp_init_chunk_t *peer_init, gfp_t gfp)
|
|
{
|
|
{
|
|
union sctp_params param;
|
|
union sctp_params param;
|
|
struct sctp_transport *transport;
|
|
struct sctp_transport *transport;
|
|
struct list_head *pos, *temp;
|
|
struct list_head *pos, *temp;
|
|
|
|
+ struct sctp_af *af;
|
|
|
|
+ union sctp_addr addr;
|
|
char *cookie;
|
|
char *cookie;
|
|
|
|
+ int src_match = 0;
|
|
|
|
|
|
/* We must include the address that the INIT packet came from.
|
|
/* We must include the address that the INIT packet came from.
|
|
* This is the only address that matters for an INIT packet.
|
|
* This is the only address that matters for an INIT packet.
|
|
@@ -2261,18 +2264,31 @@ int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid,
|
|
* added as the primary transport. The source address seems to
|
|
* added as the primary transport. The source address seems to
|
|
* be a a better choice than any of the embedded addresses.
|
|
* be a a better choice than any of the embedded addresses.
|
|
*/
|
|
*/
|
|
- if (peer_addr) {
|
|
|
|
- if(!sctp_assoc_add_peer(asoc, peer_addr, gfp, SCTP_ACTIVE))
|
|
|
|
- goto nomem;
|
|
|
|
- }
|
|
|
|
|
|
+ if(!sctp_assoc_add_peer(asoc, peer_addr, gfp, SCTP_ACTIVE))
|
|
|
|
+ goto nomem;
|
|
|
|
+
|
|
|
|
+ if (sctp_cmp_addr_exact(sctp_source(chunk), peer_addr))
|
|
|
|
+ src_match = 1;
|
|
|
|
|
|
/* Process the initialization parameters. */
|
|
/* Process the initialization parameters. */
|
|
sctp_walk_params(param, peer_init, init_hdr.params) {
|
|
sctp_walk_params(param, peer_init, init_hdr.params) {
|
|
|
|
+ if (!src_match && (param.p->type == SCTP_PARAM_IPV4_ADDRESS ||
|
|
|
|
+ param.p->type == SCTP_PARAM_IPV6_ADDRESS)) {
|
|
|
|
+ af = sctp_get_af_specific(param_type2af(param.p->type));
|
|
|
|
+ af->from_addr_param(&addr, param.addr,
|
|
|
|
+ chunk->sctp_hdr->source, 0);
|
|
|
|
+ if (sctp_cmp_addr_exact(sctp_source(chunk), &addr))
|
|
|
|
+ src_match = 1;
|
|
|
|
+ }
|
|
|
|
|
|
if (!sctp_process_param(asoc, param, peer_addr, gfp))
|
|
if (!sctp_process_param(asoc, param, peer_addr, gfp))
|
|
goto clean_up;
|
|
goto clean_up;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /* source address of chunk may not match any valid address */
|
|
|
|
+ if (!src_match)
|
|
|
|
+ goto clean_up;
|
|
|
|
+
|
|
/* AUTH: After processing the parameters, make sure that we
|
|
/* AUTH: After processing the parameters, make sure that we
|
|
* have all the required info to potentially do authentications.
|
|
* have all the required info to potentially do authentications.
|
|
*/
|
|
*/
|