#include <errno.h>
#include <stdio.h>
#include <string.h>

#include <netinet/in.h>
#include <sys/socket.h>
#include <linux/ipv6.h>

#define _GNU_SOURCE
#include <dlfcn.h>

int socket(int domain, int type, int protocol)
{
    static int (*socket_orig)(int, int, int) = NULL;
    int sock;

    if (!socket_orig) {
        socket_orig = dlsym(RTLD_NEXT, "socket");
        if (!socket_orig) {
            fprintf(stderr, "Error retrieving libc socket(): %s\n", dlerror());
            errno = EINVAL;
            return -1;
        }
    }

    sock = socket_orig(domain, type, protocol);
    if (sock < 0)
        return sock;

    if (domain == AF_INET6) {
        int val = IPV6_PREFER_SRC_PUBLIC;
        int ret = setsockopt(sock, IPPROTO_IPV6, IPV6_ADDR_PREFERENCES,
                             &val, sizeof(val));
        if (ret < 0)
            fprintf(stderr, "Could not set address preferences: %s\n",
                    strerror(errno));
    }

    return sock;
}
