Skip to content

closing a listener socket doesn't reset pending connections that haven't yet been accepted #3644

@sporksmith

Description

@sporksmith

When a listening socket is closed, any pending connections that haven't been accepted yet should be reset. The client should detect this by getting ECONNRESET or EPIPE errors when trying to operate on their end of the connection.

Unit test will be included in #3643. Current draft is below. It passes on Linux but hangs until simulation end under shadow:

fn test_close_connection_without_accept(
    domain: libc::c_int,
    sock_type: libc::c_int,
    sock_flag: libc::c_int,
) -> Result<(), String> {
    if sock_type == libc::SOCK_DGRAM {
        // Not applicable.
        return Ok(());
    }

    let fd = unsafe { libc::socket(domain, sock_type | sock_flag, 0) };
    assert!(fd >= 0);

    let (server_addr, server_addr_len) = socket_utils::autobind_helper(fd, domain);

    // listen for connections
    test_utils::assert_with_errno!(unsafe { libc::listen(fd, 10) } == 0);

    let fd_client = unsafe { libc::socket(domain, sock_type | sock_flag, 0) };
    // connect to the server address
    let rv = unsafe { libc::connect(fd_client, server_addr.as_ptr(), server_addr_len) };
    assert!(rv == 0 || (rv == -1 && test_utils::get_errno() == libc::EINPROGRESS));

    // close the listener
    let rv = unsafe { libc::close(fd) };
    assert_eq!(rv, 0);

    // client should detect that the connection/pipe was destroyed.
    let mut buf = [0u8; 10];
    test_utils::assert_with_errno!(
        unsafe { libc::recv(fd_client, buf.as_mut_ptr().cast(), buf.len(), 0) } == -1
            && test_utils::get_errno() == libc::ECONNRESET
    );
    test_utils::assert_with_errno!(
        unsafe { libc::send(fd_client, buf.as_ptr().cast(), buf.len(), 0) } == -1
            && test_utils::get_errno() == libc::EPIPE
    );

    Ok(())
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type: BugError or flaw producing unexpected results

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions