Лучший способ реализовать Socket Interface для поддержки IPV6 и IPV4 - PullRequest
1 голос
/ 05 мая 2011

Как лучше всего реализовать интерфейс сокетов для поддержки IPV6. Существующий код поддерживает только IPV4. Теперь о поддержке IPV6 у меня тоже мало сомнений ...

1) Следует ли _I заменить все API-интерфейсы IPV4 на API-интерфейсы IPV6. Скажите AF_INET по AF_INET6, sockaddr_in по sockaddr_in6 и т. Д. Будут ли эти новые API поддерживать оба протокола.

2) Или я должен поддерживать состояние таким образом ...

#ifdef IPV6_SUPPORT
    sockaddr_in6 addr;
    RTMemoryUtil::memset( &addr, 0, (int)sizeof( addr ) );
    addr.sin6_family = AF_INET6;
    addr.sin6_port   = (unsigned short)htons( port );
    RTMemoryUtil::memcpy( &addr.sin6_addr, address, (int)sizeof( *address ) );
#else
    sockaddr_in  addr;
    RTMemoryUtil::memset( &addr, 0, (int)sizeof( addr ) );
    addr.sin_family = AF_INET;
    addr.sin_port   = (unsigned short)htons( port );
    RTMemoryUtil::memcpy( &addr.sin_addr, address, (int)sizeof( *address ) );
#endif

Пожалуйста, предложите, если есть какой-либо лучший способ или каков недостаток во втором процессе.

Ответы [ 4 ]

5 голосов
/ 05 мая 2011

Технически ни вариант (1), ни (2), вы должны перейти на независимые API семейства IP и использовать struct sockaddr и struct sockaddr_storage вместо проводных структур IPv4 и IPv6. Стивенс приводит хорошие примеры создания независимого API, вот похожий метод, который я использовал:

http://code.google.com/p/openpgm/source/browse/trunk/openpgm/pgm/sockaddr.c

4 голосов
/ 05 мая 2011

Либо используйте современную библиотеку сетевого программирования, такую ​​как Boost.Asio, либо (если вы хотите сделать это способом C / sockets) интерфейс getaddrinfo. Последний был разработан около десяти лет назад, поэтому он должен быть доступен практически везде (по крайней мере, Windows, Linux, BSD, Mac OS X). Он обладает дополнительным очарованием, заключающимся в том, что он также может поддерживать экзотические сетевые протоколы при соответствующей поддержке библиотеки OS / C, поэтому вы можете претендовать на поддержку независимого от протокола распределенного облачного вычисления®.

3 голосов
/ 05 мая 2011

В зависимости от целевых платформ вы можете установить опции сокетов, чтобы позволить сокету обрабатывать как IPv4, так и IPv6, если реализован подходящий двойной стек. Это удалит большую часть работы от вашего имени.

http://long.ccaba.upc.es/long/045Guidelines/eva/ipv6.html и http://msdn.microsoft.com/en-us/library/bb513665(v=vs.85).aspx могут помочь начать работу.

Для многих случаев это может не сильно отличаться от существующего кода IPv4.

0 голосов
/ 08 февраля 2013

Другие ответы нацелены, но есть еще одна важная вещь, которую следует учитывать: структура sockaddr меньше, чем структура sockaddr_in6, необходимая для IPv6. Я портировал код, который имел это:

struct sockaddr salocal;
struct sockaddr_in * s_in = (struct sockaddr_in *) &salocal;

Замена второй строки на:

struct sockaddr_in6 * s_in6 = (struct sockaddr_in6 *) &salocal;

приводит к проблемам, потому что, хотя sockaddr_in подходит для sockaddr, sockaddr_in6 нет! Однако sockaddr_storage достаточно большой, чтобы обрабатывать как IPv4, так и IPv6.

Вместо этого переключитесь на что-то вроде:

struct sockaddr_storage salocal;
struct sockaddr_in6 * s_in6 = (struct sockaddr_in6 *) &salocal;

и затем при вызове таких методов, как bind, приведите к (struct sockaddr *).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...