void sctp_transport_free(struct sctp_transport *transport)
{
	transport->dead = 1;

	
	if (del_timer(&transport->hb_timer))
		sctp_transport_put(transport);

	if (timer_pending(&transport->T3_rtx_timer) &&
	    del_timer(&transport->T3_rtx_timer))
		sctp_transport_put(transport);

	
	if (timer_pending(&transport->proto_unreach_timer) &&
	    del_timer(&transport->proto_unreach_timer))
		sctp_association_put(transport->asoc);

	sctp_transport_put(transport);
}
예제 #2
0
/* This transport is no longer needed.  Free up if possible, or
 * delay until it last reference count.
 */
void sctp_transport_free(struct sctp_transport *transport)
{
	transport->dead = 1;

	/* Try to delete the heartbeat timer.  */
	if (del_timer(&transport->hb_timer))
		sctp_transport_put(transport);

	/* Delete the T3_rtx timer if it's active.
	 * There is no point in not doing this now and letting
	 * structure hang around in memory since we know
	 * the tranport is going away.
	 */
	if (timer_pending(&transport->T3_rtx_timer) &&
	    del_timer(&transport->T3_rtx_timer))
		sctp_transport_put(transport);


	sctp_transport_put(transport);
}
예제 #3
0
/* This transport is no longer needed.  Free up if possible, or
 * delay until it last reference count.
 */
void sctp_transport_free(struct sctp_transport *transport)
{
	transport->dead = 1;

	/* Try to delete the heartbeat timer.  */
	if (del_timer(&transport->hb_timer))
		sctp_transport_put(transport);

	/* Delete the T3_rtx timer if it's active.
	 * There is no point in not doing this now and letting
	 * structure hang around in memory since we know
	 * the tranport is going away.
	 */
	if (del_timer(&transport->T3_rtx_timer))
		sctp_transport_put(transport);

	/* Delete the ICMP proto unreachable timer if it's active. */
	if (del_timer(&transport->proto_unreach_timer))
		sctp_association_put(transport->asoc);

	sctp_transport_put(transport);
}
예제 #4
0
파일: stream.c 프로젝트: AshishNamdev/linux
struct sctp_chunk *sctp_process_strreset_outreq(
				struct sctp_association *asoc,
				union sctp_params param,
				struct sctp_ulpevent **evp)
{
	struct sctp_strreset_outreq *outreq = param.v;
	struct sctp_stream *stream = asoc->stream;
	__u16 i, nums, flags = 0, *str_p = NULL;
	__u32 result = SCTP_STRRESET_DENIED;
	__u32 request_seq;

	request_seq = ntohl(outreq->request_seq);

	if (ntohl(outreq->send_reset_at_tsn) >
	    sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map)) {
		result = SCTP_STRRESET_IN_PROGRESS;
		goto out;
	}

	if (request_seq > asoc->strreset_inseq) {
		result = SCTP_STRRESET_ERR_BAD_SEQNO;
		goto out;
	} else if (request_seq == asoc->strreset_inseq) {
		asoc->strreset_inseq++;
	}

	/* Check strreset_enable after inseq inc, as sender cannot tell
	 * the peer doesn't enable strreset after receiving response with
	 * result denied, as well as to keep consistent with bsd.
	 */
	if (!(asoc->strreset_enable & SCTP_ENABLE_RESET_STREAM_REQ))
		goto out;

	if (asoc->strreset_chunk) {
		sctp_paramhdr_t *param_hdr;
		struct sctp_transport *t;

		param_hdr = sctp_chunk_lookup_strreset_param(
					asoc, outreq->response_seq);
		if (!param_hdr || param_hdr->type !=
					SCTP_PARAM_RESET_IN_REQUEST) {
			/* same process with outstanding isn't 0 */
			result = SCTP_STRRESET_ERR_IN_PROGRESS;
			goto out;
		}

		asoc->strreset_outstanding--;
		asoc->strreset_outseq++;

		if (!asoc->strreset_outstanding) {
			t = asoc->strreset_chunk->transport;
			if (del_timer(&t->reconf_timer))
				sctp_transport_put(t);

			sctp_chunk_put(asoc->strreset_chunk);
			asoc->strreset_chunk = NULL;
		}

		flags = SCTP_STREAM_RESET_INCOMING_SSN;
	}

	nums = (ntohs(param.p->length) - sizeof(*outreq)) / 2;
	if (nums) {
		str_p = outreq->list_of_streams;
		for (i = 0; i < nums; i++) {
			if (ntohs(str_p[i]) >= stream->incnt) {
				result = SCTP_STRRESET_ERR_WRONG_SSN;
				goto out;
			}
		}

		for (i = 0; i < nums; i++)
			stream->in[ntohs(str_p[i])].ssn = 0;
	} else {
		for (i = 0; i < stream->incnt; i++)
			stream->in[i].ssn = 0;
	}

	result = SCTP_STRRESET_PERFORMED;

	*evp = sctp_ulpevent_make_stream_reset_event(asoc,
		flags | SCTP_STREAM_RESET_OUTGOING_SSN, nums, str_p,
		GFP_ATOMIC);

out:
	return sctp_make_strreset_resp(asoc, result, request_seq);
}