Эффективный способ хранения адресов IPv4 / IPv6

Я работаю над сетевым проектом C / C ++, чтобы он мог использовать сетевые стеки IPv4 и IPv6.
Проект работает только на Linux.
Итак, я попытался найти эффективный способ хранения IP-адресов и разграничения семейств протоколов.
Первым подходом было объединение:

struct ip_addr {
uint8_t fam; // socket family type
union {
struct in_addr ipv4_sin_addr;
struct in6_addr ipv6_sin_addr;
}addr;
};

Второй подход заключался в определении typedef std::vector<unsigned char> IPAddressNumberи сделать разницу после количества байтов от вектора.

Третий подход заключался в использовании int128_t / uint128_t или __int128_t из gcc.

В этом последнем случае я хотел бы знать, из какой версии GCC поддерживаются эти типы, для каких платформ (особенно IA-32 / IA-64), а также о наличии известных ошибок. Кроме того, какое из вышеуказанных решений может быть наиболее удобным?

7

Решение

Как указано в 1-й ответ Начиная с GCC 4.6.4, поддерживается 128-битное целое число.

Ваша проблема не в поддержке 128-битного целого, но как представить адрес IPv6 правильно.
Правильный ответ для этого, это использовать struct определения доступны из API сокетов.

Они доступны и стандартизированы для различных реализаций операционной системы стека IPv6.
Также вам не нужно беспокоиться о эффективность используя эти. Упаковка выравнивания выполнит свою работу должным образом, и вам не нужно беспокоиться о проблемах порядка байтов и порядка сетевых байтов реального представления.


Что касается ваших правок:

Вам не нужно изобретать велосипед! Уже есть соответствующие struct определения доступны в отношении AF_xxx тип семьи правильно.

Проверьте эти ресурсы для более подробных объяснений:

У нас есть IpAddr класс в производстве, который использует непрозрачный sockaddr_in* а также sockaddr_in6* указатели для инкапсуляции адреса IPv4 или IPv6 на основе sockaddr* указатель и reinterpret_cast<> на основе sa_family член структуры.

9

Другие решения

В соответствии с эта тема __int128_t а также __uint128_t были введены где-то около версии 4.2. И согласно документации GCC __int128 и его неподписанный коллега unsigned __int128 поддерживаются с GCC 4.6.4.

Обратите внимание, что непереносимое 128-битное целое число определенно не подходящий тип для сохранения и работы с адресами IPv6. Как уже упоминалось в комментариях, для этого есть специальные структуры данных, такие как sockaddr_in6.

3

По вопросам рекламы [email protected]