Поделиться через


параметр сокета SO_CONDITIONAL_ACCEPT

Параметр сокета SO_CONDITIONAL_ACCEPT позволяет приложению решить, принимать ли входящее подключение к сокету прослушивания.

Значение параметра сокета

Константой, представляющей этот параметр сокета, является 0x3002.

Синтаксис

int setsockopt(
  (SOCKET) s,      // descriptor identifying a socket 
  (int) SOL_SOCKET,   // level
  (int) SO_CONDITIONAL_ACCEPT, // optname
  (char *) optval,         // input buffer,
  (int) optlen,       // size of input buffer
);

Параметры

s [in]

Дескриптор, определяющий сокет.

level [in]

Уровень, на котором определен параметр. Для этой операции используйте SOL_SOCKET .

optname [in]

Параметр сокета, для которого необходимо задать значение. Используйте SO_CONDITIONAL_ACCEPT для этой операции.

optval [out]

Указатель на буфер, содержащий значение заданного параметра. Этот параметр должен указывать на буфер, равный или превышающий размер значения DWORD .

Это значение обрабатывается как логическое значение с 0, которое используется для обозначения FALSE (отключено), а ненулевое значение — значение TRUE (включено).

optlen [in, out]

Указатель на размер буфера optval в байтах. Этот размер должен быть равен или больше размера значения DWORD .

Возвращаемое значение

Если операция завершается успешно, функция setsockopt возвращает ноль.

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

Код ошибки Значение
WSANOTINITIALISED
Перед использованием этой функции должен быть выполнен успешный вызов WSAStartup .
WSAENETDOWN
Произошел сбой сетевой подсистемы.
WSAEFAULT
Один из параметров optval или optlen указывает на память, которая не находится в допустимой части адресного пространства пользователя. Эта ошибка также возвращается, если значение, указываемое параметром optlen , меньше размера значения DWORD .
WSAEINPROGRESS
Выполняется блокирующий вызов Windows Sockets 1.1 или поставщик услуг по-прежнему обрабатывает функцию обратного вызова.
WSAEINVAL
Параметр level неизвестен или недопустим. Эта ошибка также возвращается, если сокет уже находился в состоянии прослушивания.
WSAENOPROTOOPT
Параметр неизвестен или не поддерживается указанным семейством протоколов.
WSAENOTSOCK
Дескриптор не является сокетом.

 

Комментарии

Функция setsockopt , вызываемая с параметром сокета SO_CONDITIONAL_ACCEPT , позволяет приложению решить, принимать ли входящее подключение к сокету прослушивания. Параметр условного принятия для сокета по умолчанию отключен (имеет значение FALSE).

Если этот параметр сокета включен, стек TCP не принимает подключения автоматически. Он ожидает, пока приложение не укажет, что оно принимает подключение с помощью обратного вызова условного принятия, зарегистрированного с помощью функции WSAAccept . После получения запроса на подключение Winsock вызывает обратный вызов условного принятия, зарегистрированный приложением. Только когда обратный вызов условного принятия возвращает CF_ACCEPT Winsock уведомит транспорт о том, что подключение будет полностью принято.

Если для параметра сокета SO_CONDITIONAL_ACCEPT задано значение включено (значение TRUE), это оказывает несколько побочных эффектов на сокет:

  • Это отключает встроенные защиты от атак SYN в стеке TCP, так как теперь приложение берет на себя ответственность за прием подключений.
  • Это фактически отключает невыполненную работу по прослушивателю, так как подключения не принимаются от имени сокета прослушивания. Подключение никогда не будет полностью принято до тех пор, пока приложение не будет полностью принят с помощью механизма CF_ACCEPT .
  • Это также означает, что приложение всегда будет находиться в состоянии, чтобы легко обрабатывать обратные вызовы приема для принятия подключения. Если приложение занято другой обработкой, на стороне клиента может быть превышено время ожидания, прежде чем приложение фактически примет подключение. Это приводит к ухудшению взаимодействия с клиентом.

Как правило, main причина, по которой приложения используют условное принятие, заключается в проверке исходного IP-адреса или порта, используемого подключающимся клиентом, а затем принять или отклонить подключение. Однако приложения, скорее всего, будут работать лучше, если параметр SO_CONDITIONAL_ACCEPT не включен и приложение позволяет стеку TCP и невыполненной работе по прослушивателю работать должным образом. Затем, когда приложение обрабатывает принятое подключение, если оно находится из неправильного IP-адреса или порта источника, приложение может просто закрыть сокет. Недостаток безопасности этого поведения заключается в том, что теперь у клиента есть подтверждение того, что приложение прослушивает IP-адрес и порт, так как оно принудительно закрыло ранее принятое подключение. Однако недостатки, связанные с включением SO_CONDITIONAL_ACCEPT , как правило, перевешивают это ограничение.

Функция getsockopt , вызываемая с параметром сокета SO_CONDITIONAL_ACCEPT , позволяет приложению получить текущее состояние параметра условного принятия, хотя эта функция обычно не используется. Если приложению необходимо включить условное принятие для сокета, оно просто вызывает функцию setsockopt , чтобы включить параметр .

Обратите внимание, что файл заголовка Ws2def.h автоматически включается в Winsock2.h и никогда не должен использоваться напрямую.

Требования

Требование Значение
Минимальная версия клиента
Windows Vista [только классические приложения]
Минимальная версия сервера
Windows Server 2008 [только классические приложения]
Заголовок
Ws2def.h (включая Winsock2.h)

См. также раздел

getsockopt

setsockopt

WSAAccept