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

📄 sm_statefuns.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 5 页
字号:
	/* If there are errors need to be reported for unknown parameters,	 * include them in the outgoing INIT ACK as "Unrecognized parameter"	 * parameter.	 */	if (err_chunk) {		/* Get the "Unrecognized parameter" parameter(s) out of the		 * ERROR chunk generated by sctp_verify_init(). Since the		 * error cause code for "unknown parameter" and the		 * "Unrecognized parameter" type is the same, we can		 * construct the parameters in INIT ACK by copying the		 * ERROR causes over.		 */		unk_param = (sctp_unrecognized_param_t *)			    ((__u8 *)(err_chunk->chunk_hdr) +			    sizeof(sctp_chunkhdr_t));		/* Replace the cause code with the "Unrecognized parameter"		 * parameter type.		 */		sctp_addto_chunk(repl, len, unk_param);	}	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(new_asoc));	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));	/*	 * Note: After sending out INIT ACK with the State Cookie parameter,	 * "Z" MUST NOT allocate any resources for this new association.	 * Otherwise, "Z" will be vulnerable to resource attacks.	 */	sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());	retval = SCTP_DISPOSITION_CONSUME;cleanup:	if (err_chunk)		sctp_chunk_free(err_chunk);	return retval;nomem:	retval = SCTP_DISPOSITION_NOMEM;	goto cleanup;nomem_init:cleanup_asoc:	sctp_association_free(new_asoc);	goto cleanup;}/* * Handle simultanous INIT. * This means we started an INIT and then we got an INIT request from * our peer. * * Section: 5.2.1 INIT received in COOKIE-WAIT or COOKIE-ECHOED State (Item B) * This usually indicates an initialization collision, i.e., each * endpoint is attempting, at about the same time, to establish an * association with the other endpoint. * * Upon receipt of an INIT in the COOKIE-WAIT or COOKIE-ECHOED state, an * endpoint MUST respond with an INIT ACK using the same parameters it * sent in its original INIT chunk (including its Verification Tag, * unchanged). These original parameters are combined with those from the * newly received INIT chunk. The endpoint shall also generate a State * Cookie with the INIT ACK. The endpoint uses the parameters sent in its * INIT to calculate the State Cookie. * * After that, the endpoint MUST NOT change its state, the T1-init * timer shall be left running and the corresponding TCB MUST NOT be * destroyed. The normal procedures for handling State Cookies when * a TCB exists will resolve the duplicate INITs to a single association. * * For an endpoint that is in the COOKIE-ECHOED state it MUST populate * its Tie-Tags with the Tag information of itself and its peer (see * section 5.2.2 for a description of the Tie-Tags). * * Verification Tag: Not explicit, but an INIT can not have a valid * verification tag, so we skip the check. * * 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_2_1_siminit(const struct sctp_endpoint *ep,				    const struct sctp_association *asoc,				    const sctp_subtype_t type,				    void *arg,				    sctp_cmd_seq_t *commands){	/* Call helper to do the real work for both simulataneous and	 * duplicate INIT chunk handling.	 */	return sctp_sf_do_unexpected_init(ep, asoc, type, arg, commands);}/* * Handle duplicated INIT messages.  These are usually delayed * restransmissions. * * Section: 5.2.2 Unexpected INIT in States Other than CLOSED, * COOKIE-ECHOED and COOKIE-WAIT * * Unless otherwise stated, upon reception of an unexpected INIT for * this association, the endpoint shall generate an INIT ACK with a * State Cookie.  In the outbound INIT ACK the endpoint MUST copy its * current Verification Tag and peer's Verification Tag into a reserved * place within the state cookie.  We shall refer to these locations as * the Peer's-Tie-Tag and the Local-Tie-Tag.  The outbound SCTP packet * containing this INIT ACK MUST carry a Verification Tag value equal to * the Initiation Tag found in the unexpected INIT.  And the INIT ACK * MUST contain a new Initiation Tag (randomly generated see Section * 5.3.1).  Other parameters for the endpoint SHOULD be copied from the * existing parameters of the association (e.g. number of outbound * streams) into the INIT ACK and cookie. * * After sending out the INIT ACK, the endpoint shall take no further * actions, i.e., the existing association, including its current state, * and the corresponding TCB MUST NOT be changed. * * Note: Only when a TCB exists and the association is not in a COOKIE- * WAIT state are the Tie-Tags populated.  For a normal association INIT * (i.e. the endpoint is in a COOKIE-WAIT state), the Tie-Tags MUST be * set to 0 (indicating that no previous TCB existed).  The INIT ACK and * State Cookie are populated as specified in section 5.2.1. * * Verification Tag: Not specified, but an INIT has no way of knowing * what the verification tag could be, so we ignore it. * * 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_2_2_dupinit(const struct sctp_endpoint *ep,					const struct sctp_association *asoc,					const sctp_subtype_t type,					void *arg,					sctp_cmd_seq_t *commands){	/* Call helper to do the real work for both simulataneous and	 * duplicate INIT chunk handling.	 */	return sctp_sf_do_unexpected_init(ep, asoc, type, arg, commands);}/* Unexpected COOKIE-ECHO handler for peer restart (Table 2, action 'A') * * Section 5.2.4 *  A)  In this case, the peer may have restarted. */static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep,					const struct sctp_association *asoc,					struct sctp_chunk *chunk,					sctp_cmd_seq_t *commands,					struct sctp_association *new_asoc){	sctp_init_chunk_t *peer_init;	struct sctp_ulpevent *ev;	struct sctp_chunk *repl;	struct sctp_chunk *err;	sctp_disposition_t disposition;	/* new_asoc 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,			       sctp_source(chunk), peer_init,			       GFP_ATOMIC))		goto nomem;	/* Make sure no new addresses are being added during the	 * restart.  Though this is a pretty complicated attack	 * since you'd have to get inside the cookie.	 */	if (!sctp_sf_check_restart_addrs(new_asoc, asoc, chunk, commands)) {		return SCTP_DISPOSITION_CONSUME;	}	/* If the endpoint is in the SHUTDOWN-ACK-SENT state and recognizes	 * the peer has restarted (Action A), it MUST NOT setup a new	 * association but instead resend the SHUTDOWN ACK and send an ERROR	 * chunk with a "Cookie Received while Shutting Down" error cause to	 * its peer.	*/	if (sctp_state(asoc, SHUTDOWN_ACK_SENT)) {		disposition = sctp_sf_do_9_2_reshutack(ep, asoc,				SCTP_ST_CHUNK(chunk->chunk_hdr->type),				chunk, commands);		if (SCTP_DISPOSITION_NOMEM == disposition)			goto nomem;		err = sctp_make_op_error(asoc, chunk,					 SCTP_ERROR_COOKIE_IN_SHUTDOWN,					 NULL, 0);		if (err)			sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,					SCTP_CHUNK(err));		return SCTP_DISPOSITION_CONSUME;	}	/* For now, fail any unsent/unacked data.  Consider the optional	 * choice of resending of this data.	 */	sctp_add_cmd_sf(commands, SCTP_CMD_PURGE_OUTQUEUE, SCTP_NULL());	/* Update the content of current association. */	sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, SCTP_ASOC(new_asoc));	repl = sctp_make_cookie_ack(new_asoc, chunk);	if (!repl)		goto nomem;	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));	/* Report association restart to upper layer. */	ev = sctp_ulpevent_make_assoc_change(asoc, 0, SCTP_RESTART, 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:	return SCTP_DISPOSITION_NOMEM;}/* Unexpected COOKIE-ECHO handler for setup collision (Table 2, action 'B') * * Section 5.2.4 *   B) In this case, both sides may be attempting to start an association *      at about the same time but the peer endpoint started its INIT *      after responding to the local endpoint's INIT *//* This case represents an initialization collision.  */static sctp_disposition_t sctp_sf_do_dupcook_b(const struct sctp_endpoint *ep,					const struct sctp_association *asoc,					struct sctp_chunk *chunk,					sctp_cmd_seq_t *commands,					struct sctp_association *new_asoc){	sctp_init_chunk_t *peer_init;	struct sctp_ulpevent *ev;	struct sctp_chunk *repl;	/* new_asoc 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,			       sctp_source(chunk), peer_init,			       GFP_ATOMIC))		goto nomem;	/* Update the content of current association.  */	sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, 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_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL());	repl = sctp_make_cookie_ack(new_asoc, chunk);	if (!repl)		goto nomem;	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));	sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL());	/* 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(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:	return SCTP_DISPOSITION_NOMEM;}/* Unexpected COOKIE-ECHO handler for setup collision (Table 2, action 'C') * * Section 5.2.4 *  C) In this case, the local endpoint's cookie has arrived late. *     Before it arrived, the local endpoint sent an INIT and received an *     INIT-ACK and finally sent a COOKIE ECHO with the peer's same tag *     but a new tag of its own. *//* This case represents an initialization collision.  */static sctp_disposition_t sctp_sf_do_dupcook_c(const struct sctp_endpoint *ep,					const struct sctp_association *asoc,					struct sctp_chunk *chunk,					sctp_cmd_seq_t *commands,					struct sctp_association *new_asoc){	/* The cookie should be silently discarded.	 * The endpoint SHOULD NOT change states and should leave	 * any timers running.	 */	return SCTP_DISPOSITION_DISCARD;}/* Unexpected COOKIE-ECHO handler lost chunk (Table 2, action 'D') * * Section 5.2.4 * * D) When both local and remote tags match the endpoint should always *    enter the ESTABLISHED state, if it has not already done so. *//* This case represents an initialization collision.  */static sctp_disposition_t sctp_sf_do_dupcook_d(const struct sctp_endpoint *ep,					const struct sctp_association *asoc,					struct sctp_chunk *chunk,					sctp_cmd_seq_t *commands,					struct sctp_association *new_asoc){	struct sctp_ulpevent *ev = NULL;	struct sctp_chunk *repl;	/* Clarification from Implementor's Guide:	 * D) When both local and remote tags match the endpoint should         * enter the ESTABLISHED state, if it is in the COOKIE-ECHOED state.         * It should stop any cookie timer that may be running and send         * a COOKIE ACK.	 */	/* Don't accidentally move back into established state. */	if (asoc->state < SCTP_STATE_ESTABLISHED) {		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_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START,				SCTP_NULL());		/* 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;		sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,				SCTP_ULPEVENT(ev));	}	sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL());	repl = sctp_make_cookie_ack(new_asoc, chunk);	if (!repl)		goto nomem;	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));	sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL());	return SCTP_DISPOSITION_CONSUME;nomem:	if (ev)		sctp_ulpevent_free(ev);	return SCTP_DISPOSITION_NOMEM;}/* * Handle a duplicate COOKIE-ECHO.  This usually means a cookie-carrying * chunk was retransmitted and then delayed in the network. * * Section: 5.2.4 Handle a COOKIE ECHO when a TCB exists * * Verification Tag: None.  Do cookie validation. * * 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_2_4_dupcook(const struct sctp_endpoint *ep,					const struct sctp_association *asoc,					const sctp_subtype_t type,					void *arg,

⌨️ 快捷键说明

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