function connect($ipaddr, $port, $proto = 'tcp')
{
    my_print("Doing connect({$ipaddr}, {$port})");
    $sock = false;
    # Prefer the stream versions so we don't have to use both select functions
    # unnecessarily, but fall back to socket_create if they aren't available.
    if (is_callable('stream_socket_client')) {
        my_print("stream_socket_client({$proto}://{$ipaddr}:{$port})");
        $sock = stream_socket_client("{$proto}://{$ipaddr}:{$port}");
        my_print("Got a sock: {$sock}");
        if (!$sock) {
            return false;
        }
        if ($proto == 'tcp') {
            register_stream($sock);
        } elseif ($proto == 'udp') {
            register_stream($sock, $ipaddr, $port);
        } else {
            my_print("WTF proto is this: '{$proto}'");
        }
    } else {
        if (is_callable('fsockopen')) {
            my_print("fsockopen");
            if ($proto == 'tcp') {
                $sock = fsockopen($ipaddr, $port);
                if (!$sock) {
                    return false;
                }
                if (is_callable('socket_set_timeout')) {
                    socket_set_timeout($sock, 2);
                }
                register_stream($sock);
            } else {
                $sock = fsockopen($proto . "://" . $ipaddr, $port);
                if (!$sock) {
                    return false;
                }
                register_stream($sock, $ipaddr, $port);
            }
        } elseif (is_callable('socket_create')) {
            my_print("socket_create");
            if ($proto == 'tcp') {
                $sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
                $res = socket_connect($sock, $ipaddr, $port);
                if (!$res) {
                    return false;
                }
                register_socket($sock);
            } elseif ($proto == 'udp') {
                $sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
                register_socket($sock, $ipaddr, $port);
            }
        }
    }
    return $sock;
}
function connect($ipaddr, $port, $proto = 'tcp')
{
    my_print("Doing connect({$ipaddr}, {$port})");
    $sock = false;
    # IPv6 requires brackets around the address in some cases, but not all.
    # Keep track of the un-bracketed address for the functions that don't like
    # brackets, specifically socket_connect and socket_sendto.
    $ipf = AF_INET;
    $raw_ip = $ipaddr;
    if (FALSE !== strpos($ipaddr, ":")) {
        $ipf = AF_INET6;
        $ipaddr = "[" . $raw_ip . "]";
    }
    # Prefer the stream versions so we don't have to use both select functions
    # unnecessarily, but fall back to socket_create if they aren't available.
    if (is_callable('stream_socket_client')) {
        my_print("stream_socket_client({$proto}://{$ipaddr}:{$port})");
        $sock = stream_socket_client("{$proto}://{$ipaddr}:{$port}");
        my_print("Got a sock: {$sock}");
        if (!$sock) {
            return false;
        }
        if ($proto == 'tcp') {
            register_stream($sock);
        } elseif ($proto == 'udp') {
            register_stream($sock, $ipaddr, $port);
        } else {
            my_print("WTF proto is this: '{$proto}'");
        }
    } else {
        if (is_callable('fsockopen')) {
            my_print("fsockopen");
            if ($proto == 'tcp') {
                $sock = fsockopen($ipaddr, $port);
                if (!$sock) {
                    return false;
                }
                if (is_callable('socket_set_timeout')) {
                    socket_set_timeout($sock, 2);
                }
                register_stream($sock);
            } else {
                $sock = fsockopen($proto . "://" . $ipaddr, $port);
                if (!$sock) {
                    return false;
                }
                register_stream($sock, $ipaddr, $port);
            }
        } else {
            if (is_callable('socket_create')) {
                my_print("socket_create");
                if ($proto == 'tcp') {
                    $sock = socket_create($ipf, SOCK_STREAM, SOL_TCP);
                    $res = socket_connect($sock, $raw_ip, $port);
                    if (!$res) {
                        return false;
                    }
                    register_socket($sock);
                } elseif ($proto == 'udp') {
                    $sock = socket_create($ipf, SOCK_DGRAM, SOL_UDP);
                    register_socket($sock, $raw_ip, $port);
                }
            }
        }
    }
    return $sock;
}