Repository: node
Issue: v18.18.2 -> v18.19.0 regression: "fetch failed" when HTTP server stopped and started on same port
Labels: http,fetch

### Version

v18.19.0

### Platform

Darwin G34X7RD99C 23.2.0 Darwin Kernel Version 23.2.0: Wed Nov 15 21:53:18 PST 2023; root:xnu-10002.61.3~2/RELEASE_ARM64_T6000 arm64

### Subsystem

fetch

### What steps will reproduce the bug?

Run the following script:

```
const http = require('node:http');

const runServerAndFetch = async () => {
  const sockets = [];
  const server = http.createServer((req, res) => {
    res.end();
  });

  server.on('request', req => {
    sockets.push(req.socket);
  });
  await new Promise(res => {
    server.listen(10000, res);
  });

  await fetch(`http://localhost:10000`);

  await new Promise(res => {
    setTimeout(() => { // Interestingly, there's no error if this `setTimeout` is removed with its contents inlined.
      sockets.forEach(socket => socket.end());
      server.close(res);
    }, 0);
  });
};

const main = async () => {
  await runServerAndFetch();
  await runServerAndFetch();
};

main();
```

### How often does it reproduce? Is there a required condition?

Consistent reproduce

### What is the expected behavior? Why is that the expected behavior?

Ideally, both times the server is started and a `fetch(...)` is made, it should receive a `200` happily, and the script should exit without any output.

### What do you see instead?

```
node:internal/deps/undici/undici:11730
    Error.captureStackTrace(err, this);
          ^

TypeError: fetch failed
    at Object.fetch (node:internal/deps/undici/undici:11730:11)
    at async runServerAndFetch (/Users/mhentges/dev/backstage-quickstart/node.js:16:3)
    at async main (/Users/mhentges/dev/backstage-quickstart/node.js:28:3) {
  cause: SocketError: other side closed
      at Socket.onSocketEnd (node:internal/deps/undici/undici:8280:26)
      at Socket.emit (node:events:529:35)
      at endReadableNT (node:internal/streams/readable:1400:12)
      at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
    code: 'UND_ERR_SOCKET',
    socket: {
      localAddress: '::1',
      localPort: 56324,
      remoteAddress: undefined,
      remotePort: undefined,
      remoteFamily: undefined,
      timeout: undefined,
      bytesWritten: 340,
      bytesRead: 122
    }
  }
}

Node.js v18.19.0
```

### Additional information

The reproduce example I've used is simplified and is not conventionally handling request lifecycles properly.
Importantly, this bug can be reproduced using the [library the example reproduce is based on](https://github.com/hunterloftis/stoppable):

```
const http = require('node:http');
const stoppable = require('stoppable');

const runServerAndFetch = async () => {
  const server = http.createServer((req, res) => {
    res.end();
  });
  const stoppableServer = stoppable(server);

  await new Promise(res => {
    server.listen(10000, res);
  });

  await fetch(`http://localhost:10000`);

  await new Promise(res => {
    stoppableServer.stop(res);
  });
};

const main = async () => {
  await runServerAndFetch();
  await runServerAndFetch();
};

main();
```