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

标准定义的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);

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值