Solaris 10: корректно обрабатывать ошибку ENOBUFS при изменении буфера сокета - PullRequest
3 голосов
/ 13 сентября 2010

Я наткнулся на своеобразную разницу между сокетами Solaris 10 и другими сокетами Linux / * NIX. Пример:

int temp1, rc;
temp1 = 161024;  /* from config, a value greater than system limit */
rc = setsockopt( sd, SOL_SOCKET, SO_RCVBUF, &temp1, sizeof(temp1);

Приведенный выше код будет иметь rc == 0 во всех системах - Linux, HP-UX и AIX - кроме Solaris 10. Другие системы молча обрезают предоставленное значение до допустимого максимума. Solaris 10 законно завершается с ошибкой errno == ENOBUFS, указывающей на ошибку конфигурации.

После некоторого обсуждения было решено, что, поскольку конкретное приложение является критическим, а не дает сбой, оно должно продолжать работать как можно более изящно:

  1. В файле журнала выдается предупреждение о несоответствии конфигурации (просто, добавьте проверку с помощью getsockopt()) и
  2. Попробуйте установить максимальный размер буфера (чтобы получить максимально возможную производительность).

№ 2, где я застрял. Во всех системах, отличных от Solaris, мне не нужно ничего делать: сокеты уже делают это для меня.

Но на Солярисе я в недоумении, что делать. Я реализовал некоторую тривиальную дихотомию вокруг условия (setsockopt(...) == -1 && errno == ENOBUFS), чтобы найти максимальный размер буфера, но это выглядит ужасно. (Также у меня нет контекста для сохранения результатов поиска: поиск пришлось бы повторять для каждого соединения с такой плохой конфигурацией. Глобальные переменные проблематичны, поскольку код находится внутри разделяемой библиотеки и используется из приложения MT.)

Есть ли какой-нибудь лучший способ для определения максимально допустимого размера буфера в Solaris 10 с помощью API сокетов? *1024*

Есть ли какой-либо способ сообщить API сокетов Solaris обрезать значение, как это делают другие системы?

1 Ответ

2 голосов
/ 13 сентября 2010

В данный момент у меня нет доступа к системе Solaris 10, но согласно документации Oracle вы можете использовать утилиту ndd для запроса (и установки) настроенных максимумов размера буфера.для TCP и UDP:

$ ndd -get /dev/tcp tcp_max_buf
$ ndd -get /dev/udp udp_max_buf

Я не знаю о C API, но, может быть, то, что ndd использует, выставлено?

...