您的位置:首页 > 运维架构 > Linux

SCTP在LINUX中的实现:ABORT的各种场景

2016-11-16 21:56 183 查看
标准定义的ABORT格式如下:

ABORT chunk:
 0                   1                   2                   3

 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

| Type = 6      |Reserved     |T|          Length               |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

\                                                               \

/           zero or more Error Causes                           /

\                                                               \

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Error Cause:
 0                   1                   2                   3

 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

|      Cause Code               |        Cause Length           |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

/                 Cause-Specific Information                    /

\                                                               \

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Cause Code

Value Cause Code

--------- ----------------

1 Invalid Stream Identifier

2 Missing Mandatory Parameter

3 Stale Cookie Error

4 Out of Resource

5 Unresolvable Address

6 Unrecognized Chunk Type

7 Invalid Mandatory Parameter

8 Unrecognized Parameters

9 No User Data

10 Cookie Received While Shutting Down

11 Restart of an Association with New Addresses

12 User Initiated Abort

13 Protocol Violation

有一点需要注意:SCTP协议在linux的实现中,当ASSOCIATION的连续重传次数超过门限之后,只会将ASSOCIATION在本地关闭(即释放ASSOCIATION的相关内存),而不会向对端发送ABORT(和freeBSD的处理不同)。那何时向对端发送ABORT呢?要等收到对端的SCTP包之后,此时由于找不到对应的ASSOCIATION,会作为收到“Out of the Blue”的SCTP包而回ABORT。以下列出linux内核中触发abort的地方:

*************************1**************************************************
sctp_make_abort_no_data(asoc, chunk, tsn);

 sctp_make_abort(asoc, chunk, sizeof(sctp_errhdr_t) + sizeof(tsn))

 payload = htonl(tsn);

 sctp_init_cause(retval, SCTP_ERROR_NO_DATA, sizeof(payload));

  err.cause = cause_code;

  len = sizeof(sctp_errhdr_t) + paylen;

  err.length  = htons(len);

 sctp_addto_chunk(retval, sizeof(payload), (const void *)&payload);

*************************2**************************************************
sctp_close(struct sock *sk, long timeout)

 sctp_make_abort_user(asoc, NULL, 0);

  sctp_make_abort(asoc, NULL, sizeof(sctp_errhdr_t) + paylen);

  sctp_init_cause(retval, SCTP_ERROR_USER_ABORT, paylen);

   err.cause = cause_code;

   len = sizeof(sctp_errhdr_t) + paylen;

   err.length  = htons(len);
*************************3**************************************************
sctp_sf_abort_violation()

 sctp_make_abort_violation(*chunk, *payload, size_t paylen)

  retval = sctp_make_abort(asoc, chunk, sizeof(sctp_errhdr_t) + paylen + sizeof(sctp_paramhdr_t));

  sctp_init_cause(retval, SCTP_ERROR_PROTO_VIOLATION, paylen + sizeof(sctp_paramhdr_t));

   err.cause = cause_code;

   len = sizeof(sctp_errhdr_t) + paylen;

   err.length  = htons(len);

  phdr.type = htons(chunk->chunk_hdr->type);

  phdr.length = chunk->chunk_hdr->length;

  sctp_addto_chunk(retval, paylen, payload);

  sctp_addto_param(retval, sizeof(sctp_paramhdr_t), &phdr);
*************************4**************************************************
sctp_process_inv_paramlength()

 sctp_make_violation_paramlen()

  retval = sctp_make_abort(asoc, chunk, payload_len);

  sctp_init_cause(retval, SCTP_ERROR_PROTO_VIOLATION, sizeof(error) + sizeof(sctp_paramhdr_t));

   err.cause = cause_code;

   len = sizeof(sctp_errhdr_t) + paylen;

   err.length  = htons(len);

  sctp_addto_chunk(retval, sizeof(error), error);

  sctp_addto_param(retval, sizeof(sctp_paramhdr_t), param);
*************************5**************************************************
sctp_sf_violation_paramlen() // only for ASCONF ASCONF_ACK

 sctp_make_violation_paramlen()

  retval = sctp_make_abort(asoc, chunk, payload_len);

  sctp_init_cause(retval, SCTP_ERROR_PROTO_VIOLATION, sizeof(error) + sizeof(sctp_paramhdr_t));

   err.cause = cause_code;

   len = sizeof(sctp_errhdr_t) + paylen;

   err.length  = htons(len);

  sctp_addto_chunk(retval, sizeof(error), error);

  sctp_addto_param(retval, sizeof(sctp_paramhdr_t), param);
*************************6**************************************************
/*

 * Generate an ABORT in response to a packet.

 *

 * Section: 8.4 Handle "Out of the blue" Packets, sctpimpguide 2.41

 *

 * 8) The receiver should respond to the sender of the OOTB packet with

 *    an ABORT.  When sending the ABORT, the receiver of the OOTB packet

 *    MUST fill in the Verification Tag field of the outbound packet

 *    with the value found in the Verification Tag field of the OOTB

 *    packet and set the T-bit in the Chunk Flags to indicate that the

 *    Verification Tag is reflected.  After sending this ABORT, the

 *    receiver of the OOTB packet shall discard the OOTB packet and take

 *    no further action.

 *

 * Verification Tag:

 *

 * The return value is the disposition of the chunk.

*/
sctp_sf_tabort_8_4_8()

 sctp_make_abort(asoc, chunk, 0);

 *************************7**************************************************
sctp_sf_do_asconf_ack()

 abort = sctp_make_abort(asoc, asconf_ack,

    sizeof(sctp_errhdr_t));

 if (abort) {

  sctp_init_cause(abort, SCTP_ERROR_ASCONF_ACK, 0);

  sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,

    SCTP_CHUNK(abort));

 }
*************************8**************************************************
sctp_sf_do_asconf_ack()

 abort = sctp_make_abort(asoc, asconf_ack,

    sizeof(sctp_errhdr_t));

 if (abort) {

  sctp_init_cause(abort, SCTP_ERROR_RSRC_LOW, 0);

  sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,

    SCTP_CHUNK(abort));

 }
*************************9**************************************************
/* sctpimpguide-05 Section 2.12.2

 * The sender of the SHUTDOWN MAY also start an overall guard timer

 * 'T5-shutdown-guard' to bound the overall time for shutdown sequence.

 * At the expiration of this timer the sender SHOULD abort the association

 * by sending an ABORT chunk.

 */
sctp_sf_t5_timer_expire()

 reply = sctp_make_abort(asoc, NULL, 0);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  SCTP linux
相关文章推荐