Efficient way to store IPv4/IPv6 addresses

前端 未结 3 1629
春和景丽
春和景丽 2021-01-12 06:27

I am working on a C/C++ networking project that it should be able to both use the IPv4 and IPv6 networking stacks. The project works only on Linux. So, I tried to find an e

相关标签:
3条回答
  • 2021-01-12 06:57

    As stated in the 1st answer 128 bit integer support is available since GCC 4.6.4.

    Your problem isn't 128 bit integer support, but how to represent an IPv6 address correctly.
    The correct answer for this, is to use the struct definitions available from the socket API.

    These are available and standardized for various operating system implementations of the IPv6 stack.
    Also you don't need to worry about efficiency using these. Alignment packing will do its work properly, and you don't have to care about endianess vs network byte order issues of the actual representation.


    As for your edits:

    You don't have to reinvent the wheel! There are already appropriate struct definitions available respecting the AF_xxx family type correctly.

    Check these resources for more detailed explanations:

    • Understanding struct sockaddr.
    • sys/socket.h - main sockets header
    • netinet/in.h - Internet address family

    We have an IpAddr class in production, that uses the opaque sockaddr_in* and sockaddr_in6* pointers to encapsulate either an IPv4 or IPv6 address based on a sockaddr* pointer, and reinterpret_cast<> based on the sa_family member of the structure.

    0 讨论(0)
  • 2021-01-12 07:00

    According to this thread __int128_t and __uint128_t were introduced somewhere around version 4.2. And according to GCC's documentation __int128 and its unsigned counterpart unsigned __int128 are supported since GCC 4.6.4.

    Note that an unportable 128-bit integer is definitely not the appropriate type to save and work with IPv6 addresses. As mentioned in the comments there are special data structures for this, like sockaddr_in6.

    0 讨论(0)
  • 2021-01-12 07:21

    This code is from nginx. It's the same as 1st answer. I don't think it's a good idea to use pointer sockaddr_in* .

    typedef union {
        struct sockaddr           sockaddr;
        struct sockaddr_in        sockaddr_in;
    #if (NGX_HAVE_INET6)
        struct sockaddr_in6       sockaddr_in6;
    #endif
    #if (NGX_HAVE_UNIX_DOMAIN)
        struct sockaddr_un        sockaddr_un;
    #endif
    } ngx_sockaddr_t;
    

    https://github.com/nginx/nginx/blob/912fb44e25c6ab2598e36b4544c709b871251b2e/src/core/ngx_inet.h#L44

    0 讨论(0)
提交回复
热议问题