
Рис. 9.3. Формат упакованного списка адресов для функций SCTP
Количество адресов, передаваемых sctp_bindx, указывается в параметре addrcnt. Параметр flags сообщает функции sctp_bindx о необходимости выполнения действий, перечисленных в табл. 9.1.
Таблица 9.1. Флаги функции sctp_bindx
Значение аргумента flags Описание SCTP_BINDX_ADD_ADDR Добавляет адреса к уже определенным для сокета SCTP_BINDX_REM_ADDR Удаляет адреса из списка адресов сокетаФункцию sctp_bindx можно вызывать независимо от того, привязан ли сокет к каким-нибудь адресам. Для несвязанного сокета вызов sctp_bindx приведет к привязке указанного набора адресов. При работе с уже связанным сокетом указание флага SCTP_BINDX_ADD_ADDR позволяет добавить адреса к данному дескриптору. Флаг SCTP_BINDX_REM_ADDR предназначен для удаления адресов из списка связанных с данным дескриптором. Если sctp_bindx вызывается для прослушиваемого сокета, новая конфигурация будет использоваться только для новых ассоциаций; вызов никак не затронет уже установленные ассоциации. Флаги sctp_bindx взаимно исключают друг друга: если указать оба, функция вернет ошибку EINVAL. Номер порта во всех структурах адреса сокета должен быть одним и тем же. Он должен совпадать с тем номером порта, который был связан с данным сокетом ранее. В противном случае sctp_bindx тоже вернет ошибку EINVAL.
Если конечная точка поддерживает динамическую адресацию, вызов sctp_bindx с флагом SCTP_BINDX_REM_ADDR или SCTP_BINDX_ADD_ADDR приведет к передаче собеседнику сообщения о необходимости изменения списка адресов. Поскольку изменение списка адресов для установленной ассоциации не является обязательным, реализации, не поддерживающие эту функцию, будут при попытке ее использования возвращать ошибку EOPNOTSUPP. Обратите внимание, что для нормальной работы динамической адресации она должна поддерживаться обеими сторонами. Все это полезно в том случае, если система поддерживает динамическое предоставление интерфейсов: когда открывается доступ к новому интерфейсу Ethernet, приложение может вызвать SCTP_BINDX_ADD_ADDR и начать работать с этим интерфейсом по уже установленным ассоциациям.
9.4. Функция sctp_connectx
#include <netinet/sctp.h>
int sctp_connectx(int <i>sockfd</i>, const struct sockaddr *<i>addrs</i>, int <i>addrcnt</i>);
<i>Возвращает: 0 в случае успешного завершения, -1 в случае ошибки</i>
Функция sctp_connectx используется для соединения с многоинтерфейсным узлом. При ее вызове мы должны указать адреса собеседника в параметре addrs (количество адресов определяется параметром addrcnt). Формат структуры addrs представлен на рис. 9.3. Стек SCTP устанавливает ассоциацию, используя один или несколько адресов из переданного списка. Все адреса addrs считаются действующими и подтвержденными.
9.5. Функция sctp_getpaddrs
Функция getpeername не предназначена для использования протоколом, рассчитанным на работу с многоинтерфейсными узлами. Для сокетов SCTP она способна вернуть лишь основной адрес собеседника. Если нужны все адреса, следует вызывать функцию sctp_getpaddrs .
#include <netinet/sctp.h>
int sctp_getpaddrs(int <i>sockfd</i>, sctp_assoc_t <i>id</i>, struct sockadrrd **<i>addrs</i>);
<i>Возвращает: 0 в случае успешного завершения, -1 в случае ошибки</i>
Аргумент sockfd представляет собой дескриптор сокета, возвращаемый функцией socket. Второй аргумент задает идентификатор ассоциации для сокетов типа «один-ко-многим». Для сокетов типа «один-к-одному» этот аргумент игнорируется. addrs — адрес указателя, который функция sctp_getpaddrs заполнит упакованным списком адресов, выделив под него локальный буфер (см. рис. 9.3 и листинг 23.12). Для освобождения буфера, созданного sctp_getpaddrs, следует использовать вызов sctp_freepaddrs.
9.6. Функция sctp_freepaddrs
Функция sctp_freepaddrs освобождает ресурсы, выделенные вызовом sctp_getpaddrs.
#include <netinet/sctp.h>
void sctp_freepaddrs(struct sockaddr *<i>addrs</i>);
Здесь аргумент addrs — указатель на массив адресов, возвращаемый sctp_getpaddrs.
9.7. Функция sctp_getladdrs
Функция sctp_getladdrs может использоваться для получения списка локальных адресов, относящихся к определенной ассоциации. Эта функция бывает необходима в тех случаях, когда приложению требуется узнать, какие именно локальные адреса оно использует (набор адресов, напомним, может быть произвольным подмножеством всех адресов системы).
#include <netinet/sctp.h>
int sctp_getladdrs(int <i>sockfd</i>, sctp_assoc_t <i>id</i>, struct sockaddr **<i>addrs</i>);
<i>Возвращает: количество локальных адресов, помещенных в addrs, или -1 в случае ошибки.</i>
Здесь sockfd — дескриптор сокета, возвращаемый функцией socket. Аргумент id — идентификатор ассоциации для сокетов типа «один-ко-многим». Поле id игнорируется для сокетов типа «один-к-одному». Параметр представляет собой адрес указателя на буфер, выделяемый и заполняемый функцией sctp_getladdrs. В этот буфер помещается упакованный список адресов. Структура списка представлена на рис. 9.3 и в листинге 23.12. Для освобождения буфера процесс должен вызвать функцию sctp_freeladdrs.