代码之家  ›  专栏  ›  技术社区  ›  amsjntz

当恶意客户端执行缓慢的TCP握手时会发生什么?它会影响多线程服务器中的`accept()`调用吗?

  •  1
  • amsjntz  · 技术社区  · 5 月前

    假设我创建了一个简单的多线程TCP服务器,如下所示:

    int server_fd = socket(/* args */);
    
    setsockopt(server_fd, /* other args... */);
    bind(server_fd, /* other args... */);
    listen(server_fd, backlog);
    
    while (1) {
        int client_fd = accept(server_fd, /* other args... */);
        
        if (fork() == 0) {
            // handle client request
            close(client_fd);
            exit(0);
        }
    }
    

    这样的服务器应该能够处理许多客户端,但如果恶意客户端执行初始TCP握手的速度非常慢,会发生什么?在此期间,服务器是否仍能接受其他合法客户端,或者慢速客户端是否禁止这样做,因为调用 accept() 阻塞?

    为了澄清我的问题:
    这叫什么 accept() 在引擎盖下做什么?它是简单地接收下一个传入的套接字,并通过建立文件描述符来准备通信,还是主动与客户端通信以完成握手?等待TCP握手的过程会影响其他传入连接吗?

    1 回复  |  直到 5 月前
        1
  •  2
  •   Steffen Ullrich    5 月前

    在普通操作系统中,TCP握手由操作系统内核完成,操作系统内核可以并行处理多个挂起的握手。只有TCP握手成功后,它才会被放入已建立连接的队列中,然后可以用 accept .

    请注意,某些用户空间TCP栈或嵌入式系统中的小型TCP栈可能表现不同。

    另请注意,与TCP握手相反,TLS握手(如 SSL_accept )通常在用户空间中完成。因此,对于您的多进程或多线程设计,最好在 fork ,这样缓慢或行为不端的对等体就不会阻止并行TLS握手。