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); }
/* 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); }
/* 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); }
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); }