C ++ Winsock API, как получить IP-адрес клиента, прежде чем принимать соединение? - PullRequest
4 голосов
/ 04 апреля 2009

Я использую Winsock API (не CAsyncSocket) для создания сокета, который прослушивает входящие соединения.

Когда кто-то пытается подключиться, как я могу получить его IP-адрес ДО того, как принять соединение? Я пытаюсь заставить его принимать соединения только с определенных IP-адресов.

Спасибо

Ответы [ 4 ]

6 голосов
/ 09 июня 2009

SO_CONDITIONAL_ACCEPT опция сокета. Здесь

Кроме того, я уверен, что он доступен в XP и Server 2003, а не только в Vista.

1 голос
/ 04 апреля 2009

Две причины, по которым я не хочу принимать соединение для проверки удаленного IP-адреса:

1). Клиент увидит, что на этом порту есть прослушивающий сокет. Если я решу отклонить клиентское соединение, я бы не хотел, чтобы они знали, что на этом порту прослушивается сокет.

2). Этот метод не так эффективен и требует больше ресурсов ЦП, ОЗУ и сети; так что это не хорошо в случае атаки типа «отказ в обслуживании».

1 голос
/ 08 апреля 2009

При использовании ATM пакет CONNECT ACK будет поступать от самого последнего коммутатора, а не от конечного клиента. Итак, вам нужно будет вызвать accept () для сокета, затем посмотреть на адрес (на основе переданного addr_family) и в этот момент просто закрыть сокет. К тому времени, когда он достигнет запрашивающей стороны, он, вероятно, просто получит ошибку.

И я не уверен, сколько ресурсов, по вашему мнению, это займет, но принятие соединения находится на очень низком уровне и не будет проблемой. Отбросить их довольно легко.

Если вы подвергаетесь DoS-атаке, ваш код МОЖЕТ прекратить прослушивание в течение заданного периода времени, поэтому злоумышленник просто получит сбои, если вы так беспокоитесь об этом.

Действительно ли имеет значение, знает ли клиент, что прослушивание сокета происходит? Попробуйте использовать telnet для подключения к вашему локальному хосту через порт 137 и посмотрите, как быстро общий доступ к файлам в Windows обрывает соединение ... (Если он у вас даже включен, и если я запомнил правильный номер порта .. хе ...) *

Но на уровне РОЗЕТКИ вы не сможете делать то, что хотите. Вы говорите о переходе на уровень TCP, изучении входящих запросов на соединение и работе с ними там.

Это можно сделать, но вы говорите о драйвере ядра для этого. Я совсем не уверен, что вы можете сделать это в пользовательском режиме.

Если вы хотите, чтобы Kernel помог с этим, дайте мне знать. Возможно, я смогу привести вам несколько примеров или указаний.

Только мои два цента, и IMVHO ...

0 голосов
/ 04 апреля 2009

примите соединение, посмотрите на IP, если это не разрешено, закройте соединение

Редактировать

Я предполагаю, что вы говорите о TCP-соединении. Когда вы прослушиваете порт и соединение приходит от клиента, API выполнит трехстороннее рукопожатие TCP, и клиент будет знать, что этот порт прослушивается.

Я не уверен, существует ли способ запретить отправку каких-либо пакетов (то есть принятие соединения), чтобы вы могли сначала посмотреть на IP-адрес, а затем принять решение.

Единственный способ, которым я могу придумать, - это выполнить фильтрацию пакетов по IP-адресу источника на сетевом уровне (например, с помощью брандмауэра).

...