我在C应用程序中通过lksctp-tools(CentOS 7.3,lksctp-tools-1.0.17-2.el7.x86_64)使用Linux SCTP。 sctp_sendmsg()
函数用于与无法访问的目标主机建立新的SCTP关联时如何避免挂起。
当从C代码触发sctp_sendmsg()
以与无法访问的dest主机建立新的SCTP关联时,它挂起了几分钟,并且在Wireshark中,我看到Linux发送SCTP INIT重试。
如何避免这种死机?
是否可以配置一些超时(例如:1秒)来中断sctp_sendmsg()
,还是可以通过某种方式快速检查目标是否还活着(我不想遵循ICMP req-resp方式)
配置的TTL和标志参数无助于解决此问题。
const uint32_t ttl = 1000; //ms
rc = sctp_sendmsg(sctp_socket->fd, data.s, data.len, (struct sockaddr*)&sin, sizeof(sin), htonl(ppid), 0, 0, ttl, 0);
if (rc < 0) {
printf("Could not connect: %s\n", strerror(errno));
return 0;
}
最佳答案
我认为设置SCTP_INIT参数将有所帮助
struct sctp_initmsg {
uint16_t sinit_num_ostreams;
uint16_t sinit_max_instreams;
uint16_t sinit_max_attempts;
uint16_t sinit_max_init_timeo;
};
sinit_max_attempts: This integer specifies how many attempts the
SCTP endpoint should make at resending the INIT. This value
overrides the system SCTP 'Max.Init.Retransmits' value. The
default value of 0 indicates the use of the endpoint's default
value. This is normally set to the system's default
'Max.Init.Retransmit' value.
sinit_max_init_timeo: This value represents the largest timeout or
retransmission timeout (RTO) value (in milliseconds) to use in
attempting an INIT. Normally, the 'RTO.Max' is used to limit the
doubling of the RTO upon timeout. For the INIT message, this
value may override 'RTO.Max'. This value must not influence
'RTO.Max' during data transmission and is only used to bound the
initial setup time. A default value of 0 indicates the use of the
endpoint's default value. This is normally set to the system's
'RTO.Max' value (60 seconds).
在建立连接(或调用sctp_sendmsg)之前,请设置套接字选项,如下所示:
sctp_initmsg init;
init.sinit_max_attempts = m_nMaxAttempts;
init.sinit_max_init_timeo = m_nMaxInitTimeout;
if (setsockopt(nSockID, SOL_SCTP, SCTP_INITMSG, &init, sizeof(init)) != 0)
{
std::cout << strerror(errno);
return -1;
}
return 0;