I think this is due to how the game server binds the listening socket. At startup it will request the listening address to the query manager (with the LoadWorldConfig query). If for example it is the loopback address (127.0.0.1), it'll bind to the loopback interface which only accepts local connections, and I think the HOST and VM loopback interfaces don't communicate which might be the problem here.
I had other people with this same problem but I delayed addressing it mostly because I didn't have problems with setting up a VPS, and because I tested it using WSL on Windows which probably shared the same loopback interface. The quick fix is to modify the binding address at
communication.cc:1432:
Code:
//ServerAddress.sin_addr.s_addr = inet_addr(GameAddress);
ServerAddress.sin_addr.s_addr = htonl(INADDR_ANY);
I might commit this change to the repository but I'd still want to confirm whether this is correct. It makes sense for the loopback address (1st paragraph) but I'd expect
bind to fail with something like
EADDRNOTAVAIL if there is no interface with such address.