Commit 686ed0a0 authored by David S. Miller's avatar David S. Miller

Merge http://linux-lksctp.bkbits.net/lksctp-2.5.work

into nuts.davemloft.net:/disk1/BK/net-2.6
parents 6781fdec e343efc8
...@@ -93,6 +93,7 @@ typedef enum { ...@@ -93,6 +93,7 @@ typedef enum {
SCTP_CMD_PROCESS_OPERR, /* Process an ERROR chunk. */ SCTP_CMD_PROCESS_OPERR, /* Process an ERROR chunk. */
SCTP_CMD_REPORT_FWDTSN, /* Report new cumulative TSN Ack. */ SCTP_CMD_REPORT_FWDTSN, /* Report new cumulative TSN Ack. */
SCTP_CMD_PROCESS_FWDTSN, /* Skips were reported, so process further. */ SCTP_CMD_PROCESS_FWDTSN, /* Skips were reported, so process further. */
SCTP_CMD_CLEAR_INIT_TAG, /* Clears association peer's inittag. */
SCTP_CMD_LAST SCTP_CMD_LAST
} sctp_verb_t; } sctp_verb_t;
......
...@@ -440,6 +440,23 @@ static inline void sctp_add_cmd_sf(sctp_cmd_seq_t *seq, sctp_verb_t verb, sctp_a ...@@ -440,6 +440,23 @@ static inline void sctp_add_cmd_sf(sctp_cmd_seq_t *seq, sctp_verb_t verb, sctp_a
BUG(); BUG();
} }
/* Check VTAG of the packet matches the sender's own tag. */
static inline int
sctp_vtag_verify(const struct sctp_chunk *chunk,
const struct sctp_association *asoc)
{
/* RFC 2960 Sec 8.5 When receiving an SCTP packet, the endpoint
* MUST ensure that the value in the Verification Tag field of
* the received SCTP packet matches its own Tag. If the received
* Verification Tag value does not match the receiver's own
* tag value, the receiver shall silently discard the packet...
*/
if (ntohl(chunk->sctp_hdr->vtag) == asoc->c.my_vtag)
return 1;
return 0;
}
/* Check VTAG of the packet matches the sender's own tag OR its peer's /* Check VTAG of the packet matches the sender's own tag OR its peer's
* tag and the T bit is set in the Chunk Flags. * tag and the T bit is set in the Chunk Flags.
*/ */
......
...@@ -429,6 +429,9 @@ static void sctp_cmd_init_failed(sctp_cmd_seq_t *commands, ...@@ -429,6 +429,9 @@ static void sctp_cmd_init_failed(sctp_cmd_seq_t *commands,
sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
SCTP_ULPEVENT(event)); SCTP_ULPEVENT(event));
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
SCTP_STATE(SCTP_STATE_CLOSED));
/* SEND_FAILED sent later when cleaning up the association. */ /* SEND_FAILED sent later when cleaning up the association. */
asoc->outqueue.error = error; asoc->outqueue.error = error;
sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL()); sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
...@@ -457,6 +460,10 @@ static void sctp_cmd_assoc_failed(sctp_cmd_seq_t *commands, ...@@ -457,6 +460,10 @@ static void sctp_cmd_assoc_failed(sctp_cmd_seq_t *commands,
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
SCTP_STATE(SCTP_STATE_CLOSED)); SCTP_STATE(SCTP_STATE_CLOSED));
/* Set sk_err to ECONNRESET on a 1-1 style socket. */
if (!sctp_style(asoc->base.sk, UDP))
asoc->base.sk->sk_err = ECONNRESET;
/* SEND_FAILED sent later when cleaning up the association. */ /* SEND_FAILED sent later when cleaning up the association. */
asoc->outqueue.error = error; asoc->outqueue.error = error;
sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL()); sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
...@@ -1272,6 +1279,9 @@ int sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype, ...@@ -1272,6 +1279,9 @@ int sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype,
case SCTP_CMD_PROCESS_OPERR: case SCTP_CMD_PROCESS_OPERR:
sctp_cmd_process_operr(commands, asoc, chunk); sctp_cmd_process_operr(commands, asoc, chunk);
break; break;
case SCTP_CMD_CLEAR_INIT_TAG:
asoc->peer.i.init_tag = 0;
break;
default: default:
printk(KERN_WARNING "Impossible command: %u, %p\n", printk(KERN_WARNING "Impossible command: %u, %p\n",
cmd->verb, cmd->obj.ptr); cmd->verb, cmd->obj.ptr);
......
...@@ -171,7 +171,7 @@ sctp_disposition_t sctp_sf_do_4_C(const struct sctp_endpoint *ep, ...@@ -171,7 +171,7 @@ sctp_disposition_t sctp_sf_do_4_C(const struct sctp_endpoint *ep,
* Verification Tag field to Tag_A, and also provide its own * Verification Tag field to Tag_A, and also provide its own
* Verification Tag (Tag_Z) in the Initiate Tag field. * Verification Tag (Tag_Z) in the Initiate Tag field.
* *
* Verification Tag: No checking. * Verification Tag: Must be 0.
* *
* Inputs * Inputs
* (endpoint, asoc, chunk) * (endpoint, asoc, chunk)
...@@ -219,6 +219,12 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep, ...@@ -219,6 +219,12 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
(sk->sk_ack_backlog >= sk->sk_max_ack_backlog))) (sk->sk_ack_backlog >= sk->sk_max_ack_backlog)))
return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands); return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
/* 3.1 A packet containing an INIT chunk MUST have a zero Verification
* Tag.
*/
if (chunk->sctp_hdr->vtag != 0)
return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
/* Verify the INIT chunk before processing it. */ /* Verify the INIT chunk before processing it. */
err_chunk = NULL; err_chunk = NULL;
if (!sctp_verify_init(asoc, chunk->chunk_hdr->type, if (!sctp_verify_init(asoc, chunk->chunk_hdr->type,
...@@ -377,6 +383,9 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep, ...@@ -377,6 +383,9 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
if (!chunk->singleton) if (!chunk->singleton)
return SCTP_DISPOSITION_VIOLATION; return SCTP_DISPOSITION_VIOLATION;
if (!sctp_vtag_verify(chunk, asoc))
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
/* Grab the INIT header. */ /* Grab the INIT header. */
chunk->subh.init_hdr = (sctp_inithdr_t *) chunk->skb->data; chunk->subh.init_hdr = (sctp_inithdr_t *) chunk->skb->data;
...@@ -659,8 +668,12 @@ sctp_disposition_t sctp_sf_do_5_1E_ca(const struct sctp_endpoint *ep, ...@@ -659,8 +668,12 @@ sctp_disposition_t sctp_sf_do_5_1E_ca(const struct sctp_endpoint *ep,
const sctp_subtype_t type, void *arg, const sctp_subtype_t type, void *arg,
sctp_cmd_seq_t *commands) sctp_cmd_seq_t *commands)
{ {
struct sctp_chunk *chunk = arg;
struct sctp_ulpevent *ev; struct sctp_ulpevent *ev;
if (!sctp_vtag_verify(chunk, asoc))
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
/* RFC 2960 5.1 Normal Establishment of an Association /* RFC 2960 5.1 Normal Establishment of an Association
* *
* E) Upon reception of the COOKIE ACK, endpoint "A" will move * E) Upon reception of the COOKIE ACK, endpoint "A" will move
...@@ -807,13 +820,7 @@ sctp_disposition_t sctp_sf_beat_8_3(const struct sctp_endpoint *ep, ...@@ -807,13 +820,7 @@ sctp_disposition_t sctp_sf_beat_8_3(const struct sctp_endpoint *ep,
struct sctp_chunk *reply; struct sctp_chunk *reply;
size_t paylen = 0; size_t paylen = 0;
/* 8.5 When receiving an SCTP packet, the endpoint MUST ensure if (!sctp_vtag_verify(chunk, asoc))
* that the value in the Verification Tag field of the
* received SCTP packet matches its own Tag. If the received
* Verification Tag value does not match the receiver's own
* tag value, the receiver shall silently discard the packet...
*/
if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag)
return sctp_sf_pdiscard(ep, asoc, type, arg, commands); return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
/* 8.3 The receiver of the HEARTBEAT should immediately /* 8.3 The receiver of the HEARTBEAT should immediately
...@@ -876,11 +883,7 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep, ...@@ -876,11 +883,7 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep,
sctp_sender_hb_info_t *hbinfo; sctp_sender_hb_info_t *hbinfo;
unsigned long max_interval; unsigned long max_interval;
/* 8.5 When receiving an SCTP packet, the endpoint MUST ensure if (!sctp_vtag_verify(chunk, asoc))
* that the value in the Verification Tag field of the
* received SCTP packet matches its own Tag. ...
*/
if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag)
return sctp_sf_pdiscard(ep, asoc, type, arg, commands); return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
hbinfo = (sctp_sender_hb_info_t *) chunk->skb->data; hbinfo = (sctp_sender_hb_info_t *) chunk->skb->data;
...@@ -1130,6 +1133,12 @@ static sctp_disposition_t sctp_sf_do_unexpected_init( ...@@ -1130,6 +1133,12 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
if (!chunk->singleton) if (!chunk->singleton)
return SCTP_DISPOSITION_VIOLATION; return SCTP_DISPOSITION_VIOLATION;
/* 3.1 A packet containing an INIT chunk MUST have a zero Verification
* Tag.
*/
if (chunk->sctp_hdr->vtag != 0)
return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
/* Grab the INIT header. */ /* Grab the INIT header. */
chunk->subh.init_hdr = (sctp_inithdr_t *) chunk->skb->data; chunk->subh.init_hdr = (sctp_inithdr_t *) chunk->skb->data;
...@@ -1386,6 +1395,8 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep, ...@@ -1386,6 +1395,8 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep,
sctp_init_chunk_t *peer_init; sctp_init_chunk_t *peer_init;
struct sctp_ulpevent *ev; struct sctp_ulpevent *ev;
struct sctp_chunk *repl; struct sctp_chunk *repl;
struct sctp_chunk *err;
sctp_disposition_t disposition;
/* new_asoc is a brand-new association, so these are not yet /* new_asoc is a brand-new association, so these are not yet
* side effects--it is safe to run them here. * side effects--it is safe to run them here.
...@@ -1405,6 +1416,29 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep, ...@@ -1405,6 +1416,29 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep,
return SCTP_DISPOSITION_CONSUME; return SCTP_DISPOSITION_CONSUME;
} }
/* If the endpoint is in the SHUTDOWN-ACK-SENT state and recognizes
* the peer has restarted (Action A), it MUST NOT setup a new
* association but instead resend the SHUTDOWN ACK and send an ERROR
* chunk with a "Cookie Received while Shutting Down" error cause to
* its peer.
*/
if (sctp_state(asoc, SHUTDOWN_ACK_SENT)) {
disposition = sctp_sf_do_9_2_reshutack(ep, asoc,
SCTP_ST_CHUNK(chunk->chunk_hdr->type),
chunk, commands);
if (SCTP_DISPOSITION_NOMEM == disposition)
goto nomem;
err = sctp_make_op_error(asoc, chunk,
SCTP_ERROR_COOKIE_IN_SHUTDOWN,
NULL, 0);
if (err)
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
SCTP_CHUNK(err));
return SCTP_DISPOSITION_CONSUME;
}
/* For now, fail any unsent/unacked data. Consider the optional /* For now, fail any unsent/unacked data. Consider the optional
* choice of resending of this data. * choice of resending of this data.
*/ */
...@@ -1883,6 +1917,9 @@ sctp_disposition_t sctp_sf_do_5_2_6_stale(const struct sctp_endpoint *ep, ...@@ -1883,6 +1917,9 @@ sctp_disposition_t sctp_sf_do_5_2_6_stale(const struct sctp_endpoint *ep,
sctp_addto_chunk(reply, sizeof(bht), &bht); sctp_addto_chunk(reply, sizeof(bht), &bht);
/* Clear peer's init_tag cached in assoc as we are sending a new INIT */
sctp_add_cmd_sf(commands, SCTP_CMD_CLEAR_INIT_TAG, SCTP_NULL());
/* Cast away the const modifier, as we want to just /* Cast away the const modifier, as we want to just
* rerun it through as a sideffect. * rerun it through as a sideffect.
*/ */
...@@ -2071,13 +2108,7 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown(const struct sctp_endpoint *ep, ...@@ -2071,13 +2108,7 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown(const struct sctp_endpoint *ep,
skb_pull(chunk->skb, sizeof(sctp_shutdownhdr_t)); skb_pull(chunk->skb, sizeof(sctp_shutdownhdr_t));
chunk->subh.shutdown_hdr = sdh; chunk->subh.shutdown_hdr = sdh;
/* 8.5 When receiving an SCTP packet, the endpoint MUST ensure if (!sctp_vtag_verify(chunk, asoc))
* that the value in the Verification Tag field of the
* received SCTP packet matches its own Tag. If the received
* Verification Tag value does not match the receiver's own
* tag value, the receiver shall silently discard the packet...
*/
if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag)
return sctp_sf_pdiscard(ep, asoc, type, arg, commands); return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
/* Upon the reception of the SHUTDOWN, the peer endpoint shall /* Upon the reception of the SHUTDOWN, the peer endpoint shall
...@@ -2190,13 +2221,7 @@ sctp_disposition_t sctp_sf_do_ecn_cwr(const struct sctp_endpoint *ep, ...@@ -2190,13 +2221,7 @@ sctp_disposition_t sctp_sf_do_ecn_cwr(const struct sctp_endpoint *ep,
sctp_cwrhdr_t *cwr; sctp_cwrhdr_t *cwr;
struct sctp_chunk *chunk = arg; struct sctp_chunk *chunk = arg;
/* 8.5 When receiving an SCTP packet, the endpoint MUST ensure if (!sctp_vtag_verify(chunk, asoc))
* that the value in the Verification Tag field of the
* received SCTP packet matches its own Tag. If the received
* Verification Tag value does not match the receiver's own
* tag value, the receiver shall silently discard the packet...
*/
if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag)
return sctp_sf_pdiscard(ep, asoc, type, arg, commands); return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
cwr = (sctp_cwrhdr_t *) chunk->skb->data; cwr = (sctp_cwrhdr_t *) chunk->skb->data;
...@@ -2246,13 +2271,7 @@ sctp_disposition_t sctp_sf_do_ecne(const struct sctp_endpoint *ep, ...@@ -2246,13 +2271,7 @@ sctp_disposition_t sctp_sf_do_ecne(const struct sctp_endpoint *ep,
sctp_ecnehdr_t *ecne; sctp_ecnehdr_t *ecne;
struct sctp_chunk *chunk = arg; struct sctp_chunk *chunk = arg;
/* 8.5 When receiving an SCTP packet, the endpoint MUST ensure if (!sctp_vtag_verify(chunk, asoc))
* that the value in the Verification Tag field of the
* received SCTP packet matches its own Tag. If the received
* Verification Tag value does not match the receiver's own
* tag value, the receiver shall silently discard the packet...
*/
if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag)
return sctp_sf_pdiscard(ep, asoc, type, arg, commands); return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
ecne = (sctp_ecnehdr_t *) chunk->skb->data; ecne = (sctp_ecnehdr_t *) chunk->skb->data;
...@@ -2309,13 +2328,7 @@ sctp_disposition_t sctp_sf_eat_data_6_2(const struct sctp_endpoint *ep, ...@@ -2309,13 +2328,7 @@ sctp_disposition_t sctp_sf_eat_data_6_2(const struct sctp_endpoint *ep,
int tmp; int tmp;
__u32 tsn; __u32 tsn;
/* RFC 2960 8.5 Verification Tag if (!sctp_vtag_verify(chunk, asoc)) {
*
* When receiving an SCTP packet, the endpoint MUST ensure
* that the value in the Verification Tag field of the
* received SCTP packet matches its own Tag.
*/
if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag) {
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG, sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
SCTP_NULL()); SCTP_NULL());
return sctp_sf_pdiscard(ep, asoc, type, arg, commands); return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
...@@ -2569,13 +2582,7 @@ sctp_disposition_t sctp_sf_eat_data_fast_4_4(const struct sctp_endpoint *ep, ...@@ -2569,13 +2582,7 @@ sctp_disposition_t sctp_sf_eat_data_fast_4_4(const struct sctp_endpoint *ep,
int tmp; int tmp;
__u32 tsn; __u32 tsn;
/* RFC 2960 8.5 Verification Tag if (!sctp_vtag_verify(chunk, asoc)) {
*
* When receiving an SCTP packet, the endpoint MUST ensure
* that the value in the Verification Tag field of the
* received SCTP packet matches its own Tag.
*/
if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag) {
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG, sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
SCTP_NULL()); SCTP_NULL());
return sctp_sf_pdiscard(ep, asoc, type, arg, commands); return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
...@@ -2745,11 +2752,7 @@ sctp_disposition_t sctp_sf_eat_sack_6_2(const struct sctp_endpoint *ep, ...@@ -2745,11 +2752,7 @@ sctp_disposition_t sctp_sf_eat_sack_6_2(const struct sctp_endpoint *ep,
sctp_sackhdr_t *sackh; sctp_sackhdr_t *sackh;
__u32 ctsn; __u32 ctsn;
/* 8.5 When receiving an SCTP packet, the endpoint MUST ensure if (!sctp_vtag_verify(chunk, asoc))
* that the value in the Verification Tag field of the
* received SCTP packet matches its own Tag. ...
*/
if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag)
return sctp_sf_pdiscard(ep, asoc, type, arg, commands); return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
/* Pull the SACK chunk from the data buffer */ /* Pull the SACK chunk from the data buffer */
...@@ -2895,6 +2898,9 @@ sctp_disposition_t sctp_sf_do_9_2_final(const struct sctp_endpoint *ep, ...@@ -2895,6 +2898,9 @@ sctp_disposition_t sctp_sf_do_9_2_final(const struct sctp_endpoint *ep,
struct sctp_chunk *reply; struct sctp_chunk *reply;
struct sctp_ulpevent *ev; struct sctp_ulpevent *ev;
if (!sctp_vtag_verify(chunk, asoc))
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
/* 10.2 H) SHUTDOWN COMPLETE notification /* 10.2 H) SHUTDOWN COMPLETE notification
* *
* When SCTP completes the shutdown procedures (section 9.2) this * When SCTP completes the shutdown procedures (section 9.2) this
...@@ -3229,13 +3235,7 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn(const struct sctp_endpoint *ep, ...@@ -3229,13 +3235,7 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn(const struct sctp_endpoint *ep,
__u16 len; __u16 len;
__u32 tsn; __u32 tsn;
/* RFC 2960 8.5 Verification Tag if (!sctp_vtag_verify(chunk, asoc)) {
*
* When receiving an SCTP packet, the endpoint MUST ensure
* that the value in the Verification Tag field of the
* received SCTP packet matches its own Tag.
*/
if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag) {
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG, sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
SCTP_NULL()); SCTP_NULL());
return sctp_sf_pdiscard(ep, asoc, type, arg, commands); return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
...@@ -3293,13 +3293,7 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn_fast( ...@@ -3293,13 +3293,7 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn_fast(
__u16 len; __u16 len;
__u32 tsn; __u32 tsn;
/* RFC 2960 8.5 Verification Tag if (!sctp_vtag_verify(chunk, asoc)) {
*
* When receiving an SCTP packet, the endpoint MUST ensure
* that the value in the Verification Tag field of the
* received SCTP packet matches its own Tag.
*/
if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag) {
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG, sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
SCTP_NULL()); SCTP_NULL());
return sctp_sf_pdiscard(ep, asoc, type, arg, commands); return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
...@@ -3376,13 +3370,7 @@ sctp_disposition_t sctp_sf_unk_chunk(const struct sctp_endpoint *ep, ...@@ -3376,13 +3370,7 @@ sctp_disposition_t sctp_sf_unk_chunk(const struct sctp_endpoint *ep,
SCTP_DEBUG_PRINTK("Processing the unknown chunk id %d.\n", type.chunk); SCTP_DEBUG_PRINTK("Processing the unknown chunk id %d.\n", type.chunk);
/* 8.5 When receiving an SCTP packet, the endpoint MUST ensure if (!sctp_vtag_verify(unk_chunk, asoc))
* that the value in the Verification Tag field of the
* received SCTP packet matches its own Tag. If the received
* Verification Tag value does not match the receiver's own
* tag value, the receiver shall silently discard the packet.
*/
if (ntohl(unk_chunk->sctp_hdr->vtag) != asoc->c.my_vtag)
return sctp_sf_pdiscard(ep, asoc, type, arg, commands); return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
switch (type.chunk & SCTP_CID_ACTION_MASK) { switch (type.chunk & SCTP_CID_ACTION_MASK) {
......
...@@ -1164,6 +1164,11 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, ...@@ -1164,6 +1164,11 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
if (!asoc) { if (!asoc) {
SCTP_DEBUG_PRINTK("There is no association yet.\n"); SCTP_DEBUG_PRINTK("There is no association yet.\n");
if (sinfo_flags & (MSG_EOF | MSG_ABORT)) {
err = -EINVAL;
goto out_unlock;
}
/* Check for invalid stream against the stream counts, /* Check for invalid stream against the stream counts,
* either the default or the user specified stream counts. * either the default or the user specified stream counts.
*/ */
...@@ -4388,6 +4393,10 @@ static int sctp_wait_for_connect(struct sctp_association *asoc, long *timeo_p) ...@@ -4388,6 +4393,10 @@ static int sctp_wait_for_connect(struct sctp_association *asoc, long *timeo_p)
return err; return err;
do_error: do_error:
if (asoc->counters[SCTP_COUNTER_INIT_ERROR] + 1 >=
asoc->max_init_attempts)
err = -ETIMEDOUT;
else
err = -ECONNREFUSED; err = -ECONNREFUSED;
goto out; goto out;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment