racket / racket

The Racket repository
https://racket-lang.org/
Other
4.76k stars 655 forks source link

macOS `tcp-accept` blocks when compiled to standalone executable #4852

Open priime0 opened 9 months ago

priime0 commented 9 months ago

What version of Racket are you using?

8.10 CS

What program did you run?

Assume the server has the IP address of 255.255.255.255.

server.rkt (MacOS -- see OS details at the bottom):

#lang racket

(define listener (tcp-listen 10001))

(tcp-accept listener)

client.rkt (Linux (Arch)):

#lang racket

(define-values (in out)
    (tcp-connect "255.255.255.255" 10001))

Expected behaviour:

The connection resolves.

Observed behaviour:

When server.rkt is run on MacOS with the command racket server.rkt, and client.rkt is run on Linux with the command racket client.rkt, the connection resolves.

When server.rkt is compiled to an executable with one of the following three shell commands:

$ raco exe server.rkt
$ raco exe ++lib racket/tcp server.rkt # Unsure if this is necessary
$ raco exe server.rkt && raco distribute ./distro server

and then run with ./server, and client.rkt is run (either compiled to an executable or run directly with the racket shell command, then tcp-accept hangs, looping forever.

This behaviour is not observed if Linux runs server.rkt, either compiled to an executable or run directly with the racket shell command. It is also not observed if we run raco make server.rkt and racket server.rkt.

Please include any other relevant details

Possible issues:

CC @AndreyPiterkin

MacOS:

    System Software Overview:

      System Version: macOS 14.0 (23A344)
      Kernel Version: Darwin 23.0.0
      Boot Volume: Macintosh HD
      Boot Mode: Normal
      User Name: xxxxxxxxx
      Secure Virtual Memory: Enabled
      System Integrity Protection: Enabled
      Time since boot: 1 day, 1 hour, 39 minutes
mflatt commented 9 months ago

I think I'm missing an ingedient, since I have not been able to replicate this behavior on macOS 13 or 14. For the server's address as used by the client, I've tried using "localhost" and the IPv4 address associated with en0.

Are you using the address associated with en0 on the server, or something else?

Do you see this behavior on just one macOS machine as the server, or on more than one (if you have multiple machines available to try)?

AndreyPiterkin commented 9 months ago

When we compiled to a standalone executable, it would work when running both programs on the same Mac, but we observed that it would fail to connect only when using the Mac as a server for another machine to connect to.

As for the address, we were using "localhost" for the machine, and we have also tried using the broadcast feature, so both of (tcp-listen 10001 <max-allow-wait> <reuse?> #f) and (tcp-listen 10001 <max-allow-wait> <reuse?> "localhost") with various configurations for the other two arguments.

mflatt commented 8 months ago

When two machines are involved, then using "localhost" certainly won't work. Even if "localhost" is used only for tcp-listen, that constrains the listener to accept connections only on the loopback device.

There may be some confusion here with the notion of "broadcast" address. Using #f as the last argument for tcp-listener isn't related to the broadcast address, 255.255.255.255, on a given network. A #f last argument means to listen at all the devices available on the server machine, where each device will have its own specific IP address for the network that it's connected to. A second machine would have to use that IP address to refer to the listener on the relevant network.