在阅读TCP源码时,我发现一个困惑的事情:
我知道 TCP 在 3 次握手中有两个队列:
SYN回的连接ACK + SYN,我们称之为syn 队列。但是在阅读代码时,我发现listen()will call inet_csk_listen_start(),它将调用reqsk_queue_alloc()create icsk_accept_queue。并且该队列用于 中accept(),当我们发现队列不为空时,我们将从它获取连接并返回。
更重要的是,跟踪接收过程后,调用堆栈是这样的
tcp_v4_rcv()->tcp_v4_do_rcv()->tcp_rcv_state_process()
Run Code Online (Sandbox Code Playgroud)
收到第一次握手时,服务器状态为 LISTEN。所以它会调用
`tcp_v4_conn_request()->tcp_conn_request()`
Run Code Online (Sandbox Code Playgroud)
在tcp_conn_request()
if (!want_cookie)
// Add the req into the queue
inet_csk_reqsk_queue_hash_add(sk, req, tcp_timeout_init((struct sock *)req));
Run Code Online (Sandbox Code Playgroud)
但这里的队列正是icsk_accept_queue,而不是 syn 队列。
void inet_csk_reqsk_queue_hash_add(struct sock *sk, struct request_sock *req,
unsigned long timeout)
{
reqsk_queue_hash_req(req, timeout);
inet_csk_reqsk_queue_added(sk);
}
static inline void inet_csk_reqsk_queue_added(struct sock *sk)
{ …Run Code Online (Sandbox Code Playgroud) 在论文 \xe3\x80\x8a In Search of an Understanding Consensus Algorithm \xe3\x80\x8b 中,图 8 显示了(d)和(e)中的一个问题,即一些旧日志可能会被覆盖并且永远不会回来。
\n\n在第 5.4.2 节中,它说\xe2\x80\x9c 为了消除如图 8 中的问题,Raft 从不通过计算副本来提交前一项的日志条目。通过计算副本数,仅提交来自leader\xe2\x80\x99s当前任期的日志条目;一旦以这种方式提交了当前术语中的条目,则由于 Log Matching Property\xe2\x80\x9d ,所有先前的条目都会间接提交。
\n\n我对这部分感到困惑,它在图 8 中是如何工作的?什么会发生,什么不会发生?
\n