⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sm_statefuns.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (!sctp_verify_init(asoc, chunk->chunk_hdr->type,			      (sctp_init_chunk_t *)chunk->chunk_hdr, chunk,			      &err_chunk)) {		SCTP_INC_STATS(SCTP_MIB_ABORTEDS);		/* This chunk contains fatal error. It is to be discarded.		 * Send an ABORT, with causes if there is any.		 */		if (err_chunk) {			packet = sctp_abort_pkt_new(ep, asoc, arg,					(__u8 *)(err_chunk->chunk_hdr) +					sizeof(sctp_chunkhdr_t),					ntohs(err_chunk->chunk_hdr->length) -					sizeof(sctp_chunkhdr_t));			sctp_chunk_free(err_chunk);			if (packet) {				sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,						SCTP_PACKET(packet));				SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);				sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,						SCTP_STATE(SCTP_STATE_CLOSED));				sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB,						SCTP_NULL());				return SCTP_DISPOSITION_CONSUME;			} else {				sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,						SCTP_STATE(SCTP_STATE_CLOSED));				sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB,						SCTP_NULL());				return SCTP_DISPOSITION_NOMEM;			}		} else {			ret = sctp_sf_tabort_8_4_8(ep, asoc, type, arg,						   commands);			sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,					SCTP_STATE(SCTP_STATE_CLOSED));			sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB,					SCTP_NULL());			return ret;		}	}	/* Tag the variable length parameters.  Note that we never	 * convert the parameters in an INIT chunk.	 */	chunk->param_hdr.v = skb_pull(chunk->skb, sizeof(sctp_inithdr_t));	initchunk = (sctp_init_chunk_t *) chunk->chunk_hdr;	sctp_add_cmd_sf(commands, SCTP_CMD_PEER_INIT,			SCTP_PEER_INIT(initchunk));	/* 5.1 C) "A" shall stop the T1-init timer and leave	 * COOKIE-WAIT state.  "A" shall then ... start the T1-cookie	 * timer, and enter the COOKIE-ECHOED state.	 */	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,			SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,			SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE));	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,			SCTP_STATE(SCTP_STATE_COOKIE_ECHOED));	/* 5.1 C) "A" shall then send the State Cookie received in the	 * INIT ACK chunk in a COOKIE ECHO chunk, ...	 */	/* If there is any errors to report, send the ERROR chunk generated	 * for unknown parameters as well.	 */	sctp_add_cmd_sf(commands, SCTP_CMD_GEN_COOKIE_ECHO,			SCTP_CHUNK(err_chunk));	return SCTP_DISPOSITION_CONSUME;nomem:	return SCTP_DISPOSITION_NOMEM;}/* * Respond to a normal COOKIE ECHO chunk. * We are the side that is being asked for an association. * * Section: 5.1 Normal Establishment of an Association, D * D) Upon reception of the COOKIE ECHO chunk, Endpoint "Z" will reply *    with a COOKIE ACK chunk after building a TCB and moving to *    the ESTABLISHED state. A COOKIE ACK chunk may be bundled with *    any pending DATA chunks (and/or SACK chunks), but the COOKIE ACK *    chunk MUST be the first chunk in the packet. * *   IMPLEMENTATION NOTE: An implementation may choose to send the *   Communication Up notification to the SCTP user upon reception *   of a valid COOKIE ECHO chunk. * * Verification Tag: 8.5.1 Exceptions in Verification Tag Rules * D) Rules for packet carrying a COOKIE ECHO * * - When sending a COOKIE ECHO, the endpoint MUST use the value of the *   Initial Tag received in the INIT ACK. * * - The receiver of a COOKIE ECHO follows the procedures in Section 5. * * Inputs * (endpoint, asoc, chunk) * * Outputs * (asoc, reply_msg, msg_up, timers, counters) * * The return value is the disposition of the chunk. */sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,				      const struct sctp_association *asoc,				      const sctp_subtype_t type, void *arg,				      sctp_cmd_seq_t *commands){	struct sctp_chunk *chunk = arg;	struct sctp_association *new_asoc;	sctp_init_chunk_t *peer_init;	struct sctp_chunk *repl;	struct sctp_ulpevent *ev;	int error = 0;	struct sctp_chunk *err_chk_p;	/* If the packet is an OOTB packet which is temporarily on the	 * control endpoint, respond with an ABORT.	 */	if (ep == sctp_sk((sctp_get_ctl_sock()))->ep)		return sctp_sf_ootb(ep, asoc, type, arg, commands);	/* "Decode" the chunk.  We have no optional parameters so we	 * are in good shape.	 */        chunk->subh.cookie_hdr =		(struct sctp_signed_cookie *)chunk->skb->data;	skb_pull(chunk->skb,		 ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t));	/* 5.1 D) Upon reception of the COOKIE ECHO chunk, Endpoint	 * "Z" will reply with a COOKIE ACK chunk after building a TCB	 * and moving to the ESTABLISHED state.	 */	new_asoc = sctp_unpack_cookie(ep, asoc, chunk, GFP_ATOMIC, &error,				      &err_chk_p);	/* FIXME:	 * If the re-build failed, what is the proper error path	 * from here?	 *	 * [We should abort the association. --piggy]	 */	if (!new_asoc) {		/* FIXME: Several errors are possible.  A bad cookie should		 * be silently discarded, but think about logging it too.		 */		switch (error) {		case -SCTP_IERROR_NOMEM:			goto nomem;		case -SCTP_IERROR_STALE_COOKIE:			sctp_send_stale_cookie_err(ep, asoc, chunk, commands,						   err_chk_p);			return sctp_sf_pdiscard(ep, asoc, type, arg, commands);		case -SCTP_IERROR_BAD_SIG:		default:			return sctp_sf_pdiscard(ep, asoc, type, arg, commands);		};	}	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(new_asoc));	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,			SCTP_STATE(SCTP_STATE_ESTABLISHED));	SCTP_INC_STATS(SCTP_MIB_CURRESTAB);	SCTP_INC_STATS(SCTP_MIB_PASSIVEESTABS);	sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL());	if (new_asoc->autoclose)		sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,				SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));	sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL());	/* Re-build the bind address for the association is done in	 * the sctp_unpack_cookie() already.	 */	/* This is a brand-new association, so these are not yet side	 * effects--it is safe to run them here.	 */	peer_init = &chunk->subh.cookie_hdr->c.peer_init[0];	if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type,			       &chunk->subh.cookie_hdr->c.peer_addr,			       peer_init, GFP_ATOMIC))		goto nomem_init;	repl = sctp_make_cookie_ack(new_asoc, chunk);	if (!repl)		goto nomem_repl;	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));	/* RFC 2960 5.1 Normal Establishment of an Association	 *	 * D) IMPLEMENTATION NOTE: An implementation may choose to	 * send the Communication Up notification to the SCTP user	 * upon reception of a valid COOKIE ECHO chunk.	 */	ev = sctp_ulpevent_make_assoc_change(new_asoc, 0, SCTP_COMM_UP, 0,					     new_asoc->c.sinit_num_ostreams,					     new_asoc->c.sinit_max_instreams,					     GFP_ATOMIC);	if (!ev)		goto nomem_ev;	sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));	return SCTP_DISPOSITION_CONSUME;nomem_ev:	sctp_chunk_free(repl);nomem_repl:nomem_init:	sctp_association_free(new_asoc);nomem:	return SCTP_DISPOSITION_NOMEM;}/* * Respond to a normal COOKIE ACK chunk. * We are the side that is being asked for an association. * * RFC 2960 5.1 Normal Establishment of an Association * * E) Upon reception of the COOKIE ACK, endpoint "A" will move from the *    COOKIE-ECHOED state to the ESTABLISHED state, stopping the T1-cookie *    timer. It may also notify its ULP about the successful *    establishment of the association with a Communication Up *    notification (see Section 10). * * Verification Tag: * Inputs * (endpoint, asoc, chunk) * * Outputs * (asoc, reply_msg, msg_up, timers, counters) * * The return value is the disposition of the chunk. */sctp_disposition_t sctp_sf_do_5_1E_ca(const struct sctp_endpoint *ep,				      const struct sctp_association *asoc,				      const sctp_subtype_t type, void *arg,				      sctp_cmd_seq_t *commands){	struct sctp_chunk *chunk = arg;	struct sctp_ulpevent *ev;	if (!sctp_vtag_verify(chunk, asoc))		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);	/* Reset init error count upon receipt of COOKIE-ACK,	 * to avoid problems with the managemement of this	 * counter in stale cookie situations when a transition back	 * from the COOKIE-ECHOED state to the COOKIE-WAIT	 * state is performed.	 */	sctp_add_cmd_sf(commands, SCTP_CMD_COUNTER_RESET,	                SCTP_COUNTER(SCTP_COUNTER_INIT_ERROR));	/* RFC 2960 5.1 Normal Establishment of an Association	 *	 * E) Upon reception of the COOKIE ACK, endpoint "A" will move	 * from the COOKIE-ECHOED state to the ESTABLISHED state,	 * stopping the T1-cookie timer.	 */	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,			SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE));	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,			SCTP_STATE(SCTP_STATE_ESTABLISHED));	SCTP_INC_STATS(SCTP_MIB_CURRESTAB);	SCTP_INC_STATS(SCTP_MIB_ACTIVEESTABS);	sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL());	if (asoc->autoclose)		sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,				SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));	sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL());	/* It may also notify its ULP about the successful	 * establishment of the association with a Communication Up	 * notification (see Section 10).	 */	ev = sctp_ulpevent_make_assoc_change(asoc, 0, SCTP_COMM_UP,					     0, asoc->c.sinit_num_ostreams,					     asoc->c.sinit_max_instreams,					     GFP_ATOMIC);	if (!ev)		goto nomem;	sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));	return SCTP_DISPOSITION_CONSUME;nomem:	return SCTP_DISPOSITION_NOMEM;}/* Generate and sendout a heartbeat packet.  */sctp_disposition_t sctp_sf_heartbeat(const struct sctp_endpoint *ep,				     const struct sctp_association *asoc,				     const sctp_subtype_t type,				     void *arg,				     sctp_cmd_seq_t *commands){	struct sctp_transport *transport = (struct sctp_transport *) arg;	struct sctp_chunk *reply;	sctp_sender_hb_info_t hbinfo;	size_t paylen = 0;	hbinfo.param_hdr.type = SCTP_PARAM_HEARTBEAT_INFO;	hbinfo.param_hdr.length = htons(sizeof(sctp_sender_hb_info_t));	hbinfo.daddr = transport->ipaddr;	hbinfo.sent_at = jiffies;	/* Send a heartbeat to our peer.  */	paylen = sizeof(sctp_sender_hb_info_t);	reply = sctp_make_heartbeat(asoc, transport, &hbinfo, paylen);	if (!reply)		return SCTP_DISPOSITION_NOMEM;	/* Set rto_pending indicating that an RTT measurement	 * is started with this heartbeat chunk.	 */	sctp_add_cmd_sf(commands, SCTP_CMD_RTO_PENDING,			SCTP_TRANSPORT(transport));	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));	return SCTP_DISPOSITION_CONSUME;}/* Generate a HEARTBEAT packet on the given transport.  */sctp_disposition_t sctp_sf_sendbeat_8_3(const struct sctp_endpoint *ep,					const struct sctp_association *asoc,					const sctp_subtype_t type,					void *arg,					sctp_cmd_seq_t *commands){	struct sctp_transport *transport = (struct sctp_transport *) arg;	if (asoc->overall_error_count > asoc->max_retrans) {		/* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */		sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,				SCTP_U32(SCTP_ERROR_NO_ERROR));		SCTP_INC_STATS(SCTP_MIB_ABORTEDS);		SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);		return SCTP_DISPOSITION_DELETE_TCB;	}	/* Section 3.3.5.	 * The Sender-specific Heartbeat Info field should normally include	 * information about the sender's current time when this HEARTBEAT	 * chunk is sent and the destination transport address to which this	 * HEARTBEAT is sent (see Section 8.3).	 */	if (transport->hb_allowed) {		if (SCTP_DISPOSITION_NOMEM ==				sctp_sf_heartbeat(ep, asoc, type, arg,						  commands))			return SCTP_DISPOSITION_NOMEM;		/* Set transport error counter and association error counter		 * when sending heartbeat.		 */		sctp_add_cmd_sf(commands, SCTP_CMD_TRANSPORT_RESET,				SCTP_TRANSPORT(transport));	}	sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMER_UPDATE,			SCTP_TRANSPORT(transport));        return SCTP_DISPOSITION_CONSUME;}/* * Process an heartbeat request. * * Section: 8.3 Path Heartbeat * The receiver of the HEARTBEAT should immediately respond with a * HEARTBEAT ACK that contains the Heartbeat Information field copied * from the received HEARTBEAT chunk. * * Verification Tag:  8.5 Verification Tag [Normal verification] * 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 and shall not process it any further except for * those cases listed in Section 8.5.1 below. * * Inputs * (endpoint, asoc, chunk) * * Outputs * (asoc, reply_msg, msg_up, timers, counters) * * The return value is the disposition of the chunk. */sctp_disposition_t sctp_sf_beat_8_3(const struct sctp_endpoint *ep,				    const struct sctp_association *asoc,				    const sctp_subtype_t type,				    void *arg,				    sctp_cmd_seq_t *commands){	struct sctp_chunk *chunk = arg;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -