Чтение онлайн

на главную - закладки

Жанры

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

INDIGO
18. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 9. Часть 5

Не грози Дубровскому! Том IX

Панарин Антон
9. РОС: Не грози Дубровскому!
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Не грози Дубровскому! Том IX

(Противо)показаны друг другу

Юнина Наталья
Любовные романы:
современные любовные романы
эро литература
5.25
рейтинг книги
(Противо)показаны друг другу

Партиец

Семин Никита
2. Переломный век
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Партиец

Метаморфозы Катрин

Ром Полина
Фантастика:
фэнтези
8.26
рейтинг книги
Метаморфозы Катрин

Измена. Истинная генерала драконов

Такер Эйси
1. Измены по-драконьи
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Измена. Истинная генерала драконов

Чужая дочь

Зика Натаэль
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Чужая дочь

Странник

Седой Василий
4. Дворянская кровь
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Странник

Сводный гад

Рам Янка
2. Самбисты
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Сводный гад

Возвышение Меркурия. Книга 15

Кронос Александр
15. Меркурий
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 15

Муж на сдачу

Зика Натаэль
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Муж на сдачу

Диверсант

Вайс Александр
2. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
5.00
рейтинг книги
Диверсант

(Не)нужная жена дракона

Углицкая Алина
5. Хроники Драконьей империи
Любовные романы:
любовно-фантастические романы
6.89
рейтинг книги
(Не)нужная жена дракона

Тринадцатый II

NikL
2. Видящий смерть
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Тринадцатый II