diff options
Diffstat (limited to 'net/sctp/input.c')
-rw-r--r-- | net/sctp/input.c | 65 |
1 files changed, 55 insertions, 10 deletions
diff --git a/net/sctp/input.c b/net/sctp/input.c index f9a0c9276e3b..86503e7fa21e 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
@@ -911,15 +911,6 @@ static struct sctp_association *__sctp_rcv_init_lookup(struct sk_buff *skb, | |||
911 | 911 | ||
912 | ch = (sctp_chunkhdr_t *) skb->data; | 912 | ch = (sctp_chunkhdr_t *) skb->data; |
913 | 913 | ||
914 | /* If this is INIT/INIT-ACK look inside the chunk too. */ | ||
915 | switch (ch->type) { | ||
916 | case SCTP_CID_INIT: | ||
917 | case SCTP_CID_INIT_ACK: | ||
918 | break; | ||
919 | default: | ||
920 | return NULL; | ||
921 | } | ||
922 | |||
923 | /* The code below will attempt to walk the chunk and extract | 914 | /* The code below will attempt to walk the chunk and extract |
924 | * parameter information. Before we do that, we need to verify | 915 | * parameter information. Before we do that, we need to verify |
925 | * that the chunk length doesn't cause overflow. Otherwise, we'll | 916 | * that the chunk length doesn't cause overflow. Otherwise, we'll |
@@ -964,6 +955,60 @@ static struct sctp_association *__sctp_rcv_init_lookup(struct sk_buff *skb, | |||
964 | return NULL; | 955 | return NULL; |
965 | } | 956 | } |
966 | 957 | ||
958 | /* SCTP-AUTH, Section 6.3: | ||
959 | * If the receiver does not find a STCB for a packet containing an AUTH | ||
960 | * chunk as the first chunk and not a COOKIE-ECHO chunk as the second | ||
961 | * chunk, it MUST use the chunks after the AUTH chunk to look up an existing | ||
962 | * association. | ||
963 | * | ||
964 | * This means that any chunks that can help us identify the association need | ||
965 | * to be looked at to find this assocation. | ||
966 | * | ||
967 | * TODO: The only chunk currently defined that can do that is ASCONF, but we | ||
968 | * don't support that functionality yet. | ||
969 | */ | ||
970 | static struct sctp_association *__sctp_rcv_auth_lookup(struct sk_buff *skb, | ||
971 | const union sctp_addr *paddr, | ||
972 | const union sctp_addr *laddr, | ||
973 | struct sctp_transport **transportp) | ||
974 | { | ||
975 | /* XXX - walk through the chunks looking for something that can | ||
976 | * help us find the association. INIT, and INIT-ACK are not permitted. | ||
977 | * That leaves ASCONF, but we don't support that yet. | ||
978 | */ | ||
979 | return NULL; | ||
980 | } | ||
981 | |||
982 | /* | ||
983 | * There are circumstances when we need to look inside the SCTP packet | ||
984 | * for information to help us find the association. Examples | ||
985 | * include looking inside of INIT/INIT-ACK chunks or after the AUTH | ||
986 | * chunks. | ||
987 | */ | ||
988 | static struct sctp_association *__sctp_rcv_lookup_harder(struct sk_buff *skb, | ||
989 | const union sctp_addr *paddr, | ||
990 | const union sctp_addr *laddr, | ||
991 | struct sctp_transport **transportp) | ||
992 | { | ||
993 | sctp_chunkhdr_t *ch; | ||
994 | |||
995 | ch = (sctp_chunkhdr_t *) skb->data; | ||
996 | |||
997 | /* If this is INIT/INIT-ACK look inside the chunk too. */ | ||
998 | switch (ch->type) { | ||
999 | case SCTP_CID_INIT: | ||
1000 | case SCTP_CID_INIT_ACK: | ||
1001 | return __sctp_rcv_init_lookup(skb, laddr, transportp); | ||
1002 | break; | ||
1003 | |||
1004 | case SCTP_CID_AUTH: | ||
1005 | return __sctp_rcv_auth_lookup(skb, paddr, laddr, transportp); | ||
1006 | break; | ||
1007 | } | ||
1008 | |||
1009 | return NULL; | ||
1010 | } | ||
1011 | |||
967 | /* Lookup an association for an inbound skb. */ | 1012 | /* Lookup an association for an inbound skb. */ |
968 | static struct sctp_association *__sctp_rcv_lookup(struct sk_buff *skb, | 1013 | static struct sctp_association *__sctp_rcv_lookup(struct sk_buff *skb, |
969 | const union sctp_addr *paddr, | 1014 | const union sctp_addr *paddr, |
@@ -979,7 +1024,7 @@ static struct sctp_association *__sctp_rcv_lookup(struct sk_buff *skb, | |||
979 | * parameters within the INIT or INIT-ACK. | 1024 | * parameters within the INIT or INIT-ACK. |
980 | */ | 1025 | */ |
981 | if (!asoc) | 1026 | if (!asoc) |
982 | asoc = __sctp_rcv_init_lookup(skb, laddr, transportp); | 1027 | asoc = __sctp_rcv_lookup_harder(skb, paddr, laddr, transportp); |
983 | 1028 | ||
984 | return asoc; | 1029 | return asoc; |
985 | } | 1030 | } |