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);
......
This diff is collapsed.
...@@ -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,7 +4393,11 @@ static int sctp_wait_for_connect(struct sctp_association *asoc, long *timeo_p) ...@@ -4388,7 +4393,11 @@ static int sctp_wait_for_connect(struct sctp_association *asoc, long *timeo_p)
return err; return err;
do_error: do_error:
err = -ECONNREFUSED; if (asoc->counters[SCTP_COUNTER_INIT_ERROR] + 1 >=
asoc->max_init_attempts)
err = -ETIMEDOUT;
else
err = -ECONNREFUSED;
goto out; goto out;
do_interrupted: do_interrupted:
......
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