23.7. Получение адресов

23.7. Получение адресов

Поскольку протокол SCTP ориентирован на многоинтерфейсные узлы, для определения адресов локального и удаленного узла не могут использоваться те же механизмы, что и в TCP. В этом разделе мы изменим код клиента, добавив в него подписку на уведомление о событии COMMUNICATION UP. В этом уведомлении клиент будет получать сведения об адресах, между которыми установлена ассоциация. В листингах 23.9 и 23.10 представлены изменения в коде клиента. Листинги 23.11 и 23.12 содержат добавления к коду клиента.

Листинг 23.9. Клиент включает уведомления

16 bzero(&evnts, sizeof(evnts));

17 evnts.sctp_data_io_event = 1;

18 evnts.sctp_association_event = 1;

19 Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts));

20 sctpstr_cli(stdin, sock_fd, (SA*)&servaddr, sizeof(servaddr));

Включение событий и вызов функции отправки сообщения

16-20 Функция main клиента претерпевает не слишком значительные изменения. Клиент явным образом подписывается на уведомления об изменении состояния ассоциации.

Посмотрим, что нам придется изменить в функции sctpstr_cli, чтобы она смогла вызывать нашу новую функцию обработки уведомлений.

Листинг 23.10. Функция sctp_strcli, способная работать с уведомлениями

21 do {

22  len = sizeof(peeraddr);

23  rd_sz = Sctp_recvmsg(sock_fd, recvline, sizeof(recvline),

24   (SA*)&peeraddr, &len, &sri, &msg_flags);

25  if (msg_flags & MSG_NOTIFICATION)

26   check_notification(sock_fd, recvline, rd_sz);

27 } while (msg_flags & MSG_NOTIFICATION);

28 printf("From str:%d seq:%d (assoc.0x%x) ",

29 sri.sinfo_stream, sri.sinfo_ssn, (u_int)sri.sinfo_assoc_id);

30 printf("%.*s", rd_sz.recvline);

Цикл ожидания сообщения

21-24 Клиент устанавливает переменную, в которой хранится длина адреса, и вызывает функцию sctp_recvmsg для получения эхо-ответа сервера на свое сообщение.

Проверка уведомлений

25-26 Клиент проверяет, не является ли полученное сообщение уведомлением. В последнем случае он вызывает функцию обработки уведомлений, представленную в листинге 23.11.

Переход на начало цикла

27 Если сообщение действительно было уведомлением, происходит переход на начало цикла ожидания сообщений.

Отображение сообщения

28-30 Клиент отображает сообщение и переходит к ожиданию пользовательского ввода.

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

Листинг 23.11. Обработка уведомлений

//sctp/sctp_check_notify.c

 1 #include "unp.h"

 2 void

 3 check_notification(int sock_fd, char *recvline, int rd_len)

 4 {

 5  union sctp_notification *snp;

 6  struct sctp_assoc_change *sac;

 7  struct sockaddr_storage *sal, *sar;

 8  int num_rem, num_loc;

 9  snp = (union sctp_notification*)recvline;

10  if (snp->sn_header.sn_type == SCTP_ASSOC_CHANGE) {

11   sac = &snp->sn_assoc_change;

12   if ((sac->sac_state == SCTP_COMM_UP) ||

13    (sac->sac_state == SCTP_RESTART)) {

14    num_rem = sctp_getpaddrs(sock_fd, sac->sac_assoc_id, &sar);

15    printf("There are %d remote addresses and they are: ", num_rem);

16    sctp_print_addresses(sar, num_rem);

17    sctp_freepaddrs(sar);

18    num_loc = sctp_getladdrs(sock_fd.sac->sac_assoc_id, &sal);

19    printf("There are %d local addresses and they are: ", num_loc);

20    sctp_print_addresses(sal, num_loc);

21    sctp_freeladdrs(sal);

22   }

23  }

24 }

Проверка типа уведомления

9-13 Функция преобразует буфер приема к типу универсального указателя на уведомления, чтобы определить тип полученного уведомления. Из всех уведомлений нас интересуют только уведомления об изменении ассоциации, а из них — уведомления о создании или перезапуске ассоциации (SCTP_COMM_UP и SCTP_RESTART). Все прочие уведомления нас не интересуют.

Получение и вывод адресов собеседника

14-17 Функция sctp_getpaddrs возвращает нам список удаленных адресов, которые мы выводим при помощи функции sctp_print_addresses, представленной в листинге 23.12. После работы с ней мы освобождаем ресурсы, выделенные sctp_getpaddrs, вызывая функцию sctp_freepaddrs.

Получение и вывод локальных адресов

18-21 Функция sctp_getladdrs возвращает нам список локальных адресов, которые мы выводим на экран вместе с их общим количеством. После завершения работы с адресами мы освобождаем память вызовом sctp_freeladdrs.

Последняя из новых функций называется sctp_print_addresses. Она выводит на экран адреса из списка, возвращаемого функциями sctp_getpaddrs и sctp_getladdrs. Текст функции представлен в листинге 23.12.

Листинг 23.12. Вывод списка адресов

//sctp/sctp_print_addrs.c

 1 #include "unp.h"

 2 void

 3 sctp_print_addresses(struct sockaddr_storage *addrs, int num)

 4 {

 5  struct sockaddr_storage *ss;

 6  int i, salen;

 7  ss = addrs;

 8  for (i=0; i<num; i++){

 9   printf("%s ", Sock_ntop((SA*)ss, salen));

10 #ifdef HAVE_SOCKADDR_SA_LEN

11   salen = ss->ss_len;

12 #else

13   swilch (ss->ss_family) {

14   case AF_INET:

15    salen = sizeof(struct sockaddr_in);

16    break;

17 #ifdef IPV6

18   case AF_INET6:

19    salen = sizeof(struct sockaddr_in6);

20    break;

21 #endif

22   default:

23    err_auit("sctp_print_addresses: unknown AF");

24    break;

25   }

26 #endif

27   ss = (struct sockaddr_storage*)((char*)ss + salen);

28  }

29 }

Последовательная обработка адресов

7-8 Функция перебирает адреса в цикле. Общее количество адресов указывается вызывающим процессом.

Вывод адреса

9 Адрес преобразуется к удобочитаемому виду функцией sock_ntop, которая, как вы помните, должна работать со структурами адреса сокета всех форматов, поддерживаемых системой.

Определение размера адреса

10-26 Список адресов передается в упакованном формате. Это не просто массив структур sockaddr_storage. Дело в том, что структура sockaddr_storage достаточно велика, и ее нецелесообразно использовать при передаче адресов между ядром и пользовательскими процессами. В системах, где эта структура содержит внутреннее поле длины, обработка списка является делом тривиальным: достаточно извлекать длину из текущей структуры sockaddr_storage. В прочих системах длина определяется на основании семейства адреса. Если семейство не определено, функция завершает работу с сообщением об ошибке.

Перемещение указателя

27 К указателю на элемент списка прибавляется размер адреса. Таким образом осуществляется перемещение по списку адресов.

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

5.9 Форматы адресов

Из книги TCP/IP Архитектура, протоколы, реализация (включая IP версии 6 и IP Security) автора Фейт Сидни М

5.9 Форматы адресов Как показано на рис. 5.4, IP-адрес состоит из двух частей: адреса сети (network address) и локального адреса (local address). Адрес сети идентифицирует сеть, к которой подключен узел, а локальный адрес определяет отдельный узел внутри сети организации. Рис. 5.4. Формат


5.10 Классы адресов

Из книги Сетевые средства Linux автора Смит Родерик В.

5.10 Классы адресов Организация, планирующая подключение к Интернету, должна получить для себя блок уникальных IP-адресов. Этот блок выделяется соответствующей регистрационной службой.По соглашению, регистрационная служба делегирует выделение больших блоков


11.7.4 Присваивание IP-адресов

Из книги Яндекс для всех автора Абрамзон М. Г.

11.7.4 Присваивание IP-адресов Администратор конфигурирует сервер BOOTP для присваивания системам IP-адресов посредством ручного создания таблицы отображения на IP-адрес комбинации типа оборудования и аппаратного адреса клиента. Кодирование типов оборудования определяется


11.9.1 Присваивание IP-адресов

Из книги Linux и UNIX: программирование в shell. Руководство разработчика. автора Тейнсли Дэвид

11.9.1 Присваивание IP-адресов В DHCP поддерживаются три типа присвоения адресов:? Ручное, когда IP-адрес вводится на сервере и назначается клиенту постоянно? Автоматическое, когда IP-адрес выбирается сервером из пула доступных адресов и назначается клиенту


11.9.2 Аренда адресов

Из книги Анонимность и безопасность в Интернете. От «чайника» к пользователю автора Колисниченко Денис Николаевич

11.9.2 Аренда адресов Процесс выделения адресов предполагает запрос клиентом IP-адреса на определенный период времени (возможно, что и навсегда). Сервер предоставляет клиенту адрес в аренду, указывая период использования данного адреса. Клиент должен периодически


12.5 Просмотр адресов хостов

Из книги UNIX: разработка сетевых приложений автора Стивенс Уильям Ричард

12.5 Просмотр адресов хостов Как мы уже знаем, многие системы предоставляют интерактивные программы-определители, дающие возможность пользователям напрямую обращаться к серверам DNS, посылая к ним запросы и получая ответы. Приведем пример работы с


12.7 Трансляция адресов в имена

Из книги автора

12.7 Трансляция адресов в имена Система DNS обратима, т.е. может выполнять обратную трансляцию адресов в имена. Однако способ, используемый для этого в nslookup, несколько необычен:? Установить тип запроса в ptr.? Записать адрес наоборот, дописав в конце его .in-addr.arpa.Например:> set type


12.15 Трансляция адресов в имена

Из книги автора

12.15 Трансляция адресов в имена Почему необходим обратный поиск и трансляция адресов в имена? Некоторые системные программы вызывают обратный поиск с целью улучшения вывода информации для администрирования. Например, показанный ниже вывод из программы netstat представляет


22.4.1 Выделение адресов

Из книги автора

22.4.1 Выделение адресов 128-разрядное пространство адреса обеспечивает место для множества различных типов адресов, включая:? Иерархические глобальные одноадресные рассылки на основе адресов провайдеров? Иерархические глобальные одноадресные рассылки по


22.8.4 Изменение адресов

Из книги автора

22.8.4 Изменение адресов Возможность применения более одного глобального префикса упрощает переход от одного провайдера к другому.От маршрутизатора поступают значения для установки индивидуальных таймеров на каждый префикс провайдера. При переключении с одного


Маскировка адресов

Из книги автора

Маскировка адресов Как было сказано ранее, вам может потребоваться, чтобы в сообщениях вместо имени, возвращаемого по команде hostname, отображалось другое имя узла или домена. Основные средства маскировки адресов включаются посредством опции qualify_domain. С помощью данной


Маскировка адресов

Из книги автора

Маскировка адресов Опция myorigin позволяет задать имя, под которым Postfix будет представляться при взаимодействии с другими системами. По умолчанию в качестве значения данной опции задается переменная $myhostname, которая, в свою очередь, определяет доменное имя компьютера.


1.10.1. Поиск среди адресов

Из книги автора

1.10.1. Поиск среди адресов Что можно искать на Яндекс. Адреса, как не организации или компании? Это специализированный поиск, и ничего более найти здесь нельзя. Но поиск довольно своеобразный. И сейчас попробуем разобраться в этом своеобразии.Первый вариант поиска — поиск


8.6. Фильтрация MAC-адресов

Из книги автора

8.6. Фильтрация MAC-адресов В качестве дополнительного барьера можно указать список MAC-адресов сетевых адаптеров компьютеров, которые смогут получить доступ к вашему маршрутизатору. Нужно отметить, что фильтрация MAC-адресов не обеспечивает надежной защиты. Опытный


Пример: получение семейства адресов сокета

Из книги автора

Пример: получение семейства адресов сокета Функция sockfd_to_family, представленная в листинге 4.4, возвращает семейство адресов сокета.Листинг 4.4. Возвращаемое семейство адресов сокета//lib/sockfd_to_family.c 1 #include "unp.h" 2 int 3 sockfd_to_family(int sockfd) 4 { 5  union { 6   struct sockaddr sa; 7   char data[MAXSOCKADDR]; 8  }