UNIX: разработка сетевых приложений
Шрифт:
Поиск адресата и создание сокета
22-23
Мы определяем адрес назначения при помощи host_serv
и создаем сокет для отправки пакетов. Установка «закрепленного» параметра IPV6_RTHDR и вызов рабочей функции
24-27
В разделе 27.7 будет показано, что не обязательно отправлять одни и те же вспомогательные данные с каждым пакетом. Вместо этого можно вызвать setsockopt
таким образом, что один и тот же заголовок будет добавляться
ptr
не нулевой, то есть мы уже должны были выделить буфер под заголовок маршрутизации. На последнем этапе мы вызываем рабочую функцию dg_cli
, которая не меняется с листинга 8.4. Программа UDP-сервера не изменилась по сравнению с предыдущими примерами. Сервер открывает сокет и вызывает функцию
dg_echo
. В листинге 27.6 представлена функция dg_echo
, печатающая информацию о маршруте от источника (если таковой был получен) и обращающая этот маршрут для отправки сообщения в обратном направлении. Листинг 27.6. Функция dg_echo, печатающая маршрут
//ipopts/dgechoprintroute.c
1 #include "unp.h"
2 void
3 dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen)
4 {
5 int n;
6 char mesg[MAXLINE];
7 int on;
8 char control[MAXLINE];
9 struct msghdr msg;
10 struct cmsghdr *cmsg;
11 struct iovec iov[1];
12 on = 1;
13 Setsockopt(sockfd, IPPROTO_IPV6, IPV6_RECVRTHDR, &on, sizeof(on));
14 bzero(&msg, sizeof(msg));
15 iov[0].iov_base = mesg;
16 msg.msg_name = pcliaddr;
17 msg.msg_iov = iov;
18 msg.msg_iovlen = 1;
19 msg.msg_control = control;
20 for (;;) {
21 msg.msg_namelen = clilen;
22 msg.msg_controllen = sizeof(control);
23 iov[0].iov_len = MAXLINE;
24 n = Recvmsg(sockfd, &msg, 0);
25 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
26 cmsg = CMSG_NXTHDR(&msg, cmsg)) {
27 if (cmsg->cmsg_level == IPPROTO_IPV6 &&
28 cmsg->cmsg_type == IPV6_RTHDR) {
29 inet6_srcrt_print(CMSG_DATA(cmsg));
30 Inet6_rth_reverse(CMSG_DATA(cmsg), CMSG_DATA(cmsg));
31 }
32 }
33 iov[0].iov_len = n;
34 Sendmsg(sockfd, &msg, 0);
35 }
36 }
Включение
параметра IPV6_RECVRTHDR и подготовка структуры msghdr
12-13
Чтобы получить информацию о маршруте, мы должны установить параметр сокета IPV6_RECVRTHDR
. Кроме того, мы должны использовать функцию recvmsg
, поэтому мы настраиваем поля структуры msghdr
, которые не требуют изменения. Настройка изменяемых полей и вызов recvmsg
21-24
Мы устанавливаем размер полей длины и вызываем recvmsg
. Поиск и обработка маршрута от отправителя
25-32
Мы перебираем вспомогательные данные, используя CMSG_FIRSTHDR
и CMSG_NXTHDR
. Несмотря на то, что мы ожидаем получить только один объект вспомогательных данных, выполнить такой перебор всегда полезно. Если мы обнаруживаем заголовок маршрутизации, он распечатывается функцией inet6_srcrt_print
(листинг 27.7). Затем маршрут обращается функцией inet6_rth_reverse
для последующего использования при возвращении пакета клиенту. В данном случае обращение производится без копирования в новый буфер, так что можно использовать старый объект вспомогательных данных для отправки пакета клиенту. Отправка эхо-пакета
33-34
Мы устанавливаем длину пакета и передаем его клиенту вызовом sendmsg
. Благодаря наличию вспомогательных библиотечных функций IPv6 наша функция
inet6_srcrt_print
становится почти тривиальной. Листинг 27.7. Функция inet6_srcrt_print: вывод маршрута
1 #include "unp.h"
2 void
3 inet6_srcrt_print(void *ptr)
4 {
5 int i, segments;
6 char str[INET6_ADDRSTRLEN];
7 segments = Inet6_rth_segments(ptr);
8 printf("received source route: ");
9 for (i = 0; i < segments; i++)
10 printf("%s ", Inet_ntop(AF_INET6, Inet6_rth_getaddr(ptr, i),
11 str, sizeof(str)));
Поделиться:
Популярные книги
На границе империй. Том 9. Часть 5
18. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
Не грози Дубровскому! Том IX
9. РОС: Не грози Дубровскому!
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
(Противо)показаны друг другу
Любовные романы:
современные любовные романы
эро литература
5.25
рейтинг книги
Партиец
2. Переломный век
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Метаморфозы Катрин
Фантастика:
фэнтези
8.26
рейтинг книги
Измена. Истинная генерала драконов
1. Измены по-драконьи
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Чужая дочь
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Странник
4. Дворянская кровь
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Сводный гад
2. Самбисты
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Возвышение Меркурия. Книга 15
15. Меркурий
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Муж на сдачу
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Диверсант
2. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
5.00
рейтинг книги
(Не)нужная жена дракона
5. Хроники Драконьей империи
Любовные романы:
любовно-фантастические романы
6.89
рейтинг книги
Тринадцатый II
2. Видящий смерть
Фантастика:
фэнтези
попаданцы
аниме
5.00