/* The check for association's overall error counter exceeding the
* threshold is done in the state function.
*/
- asoc->overall_error_count++;
+ /* When probing UNCONFIRMED addresses, the association overall
+ * error count is NOT incremented
+ */
+ if (transport->state != SCTP_UNCONFIRMED)
+ asoc->overall_error_count++;
if (transport->state != SCTP_INACTIVE &&
(transport->error_count++ >= transport->pathmaxrxt)) {
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
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. */
asoc->outqueue.error = error;
sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
/* Mark the destination transport address as active if it is not so
* marked.
*/
- if (t->state == SCTP_INACTIVE)
+ if ((t->state == SCTP_INACTIVE) || (t->state == SCTP_UNCONFIRMED))
sctp_assoc_control_transport(asoc, t, SCTP_TRANSPORT_UP,
SCTP_HEARTBEAT_SUCCESS);
*/
hbinfo = (sctp_sender_hb_info_t *) chunk->skb->data;
sctp_transport_update_rto(t, (jiffies - hbinfo->sent_at));
+
+ /* Update the heartbeat timer. */
+ if (!mod_timer(&t->hb_timer, sctp_transport_timeout(t)))
+ sctp_transport_hold(t);
}
/* Helper function to do a transport reset at the expiry of the hearbeat
return;
}
+/* Helper function to set sk_err on a 1-1 style socket. */
+static void sctp_cmd_set_sk_err(struct sctp_association *asoc, int error)
+{
+ struct sock *sk = asoc->base.sk;
+
+ if (!sctp_style(sk, UDP))
+ sk->sk_err = error;
+}
+
/* These three macros allow us to pull the debugging code out of the
* main flow of sctp_do_sm() to keep attention focused on the real
* functionality there.
"T1 INIT Timeout adjustment"
" init_err_counter: %d"
" cycle: %d"
- " timeout: %d\n",
+ " timeout: %ld\n",
asoc->init_err_counter,
asoc->init_cycle,
asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT]);
SCTP_DEBUG_PRINTK(
"T1 COOKIE Timeout adjustment"
" init_err_counter: %d"
- " timeout: %d\n",
+ " timeout: %ld\n",
asoc->init_err_counter,
asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE]);
local_cork = 0;
asoc->peer.retran_path = t;
break;
+ case SCTP_CMD_SET_SK_ERR:
+ sctp_cmd_set_sk_err(asoc, cmd->obj.error);
+ break;
default:
printk(KERN_WARNING "Impossible command: %u, %p\n",
cmd->verb, cmd->obj.ptr);