facebook/hhvm — pull request #1599 by serphen (2014-01-19 22:56:41+00:00)
Title: Fix ambiguous key in g_persistentObjects for persistent connections

Summary: Persistent connections return the wrong socket due to ambiguous key in g_persistentObjects
Persistent connections currently return a cached connection for (key = "hostname").
Expected behaviour is to return a cached connection for (key = "hostname + port").

As a result, persistent connections write and read from the *wrong* socket if you have multiple connections to the same hostname but different port.

Redis hhvm implementation is affected by this bug (probably other modules too, but not MySQL at least, who uses its own socket cache handler).

This bug has been introduced by commit 04b77176fe0e17e4885c6465fcd98cccaf50d4a4 ("Fix sockopen_impl with IPv6 addresses")

How to reproduce:

Run two servers:

Server A: nc -l -p 4545
Server B: nc -l -p 7878

Expected output:

On port 4545:
hello_on_socket_A

On port 7878:
hello_on_socket_B

Known workaround (without recompiling hhvm):

The key is derived from Util::HostURL.getHostURL so a workaround is to explicitly pass to HostURL a port, so the used key in g_persistentObjects becomes "192.168.0.20:4545" instead of "192.168.0.20".

$A = pfsockopen('127.0.0.1:4545', 4545);
$B = pfsockopen('127.0.0.1:7878', 7878);

Fix:

Always use port in the key used in g_persistentObjects.

Side Effects: none

Revert Plan: simple