AcceptEx и OpenSSL

Я хотел бы знать, как правильно обрабатывать новое соединение от клиента с помощью AcceptEx и OpenSSL. У меня есть отлично работающий сервер, который использует AcceptEx с портами завершения ввода-вывода через обычный HTTP. Я бы хотел добавить к нему поддержку OpenSSL.

Я прочитал несколько статей в Интернете об использовании OpenSSL с неблокирующими сокетами:

Кажется, никто из них не касается того, как это сделать, потому что они в основном озабочены клиентской стороной соединения. AcceptEx устанавливает соединение с сокетом И возвращает вам первую часть данных, отправленных от клиента. В первой опубликованной мной ссылке обсуждается, как следует обрабатывать входящие данные с помощью IOCP. Я пробовал то, что там написано, пока безуспешно. В основном я вижу на своем сервере следующее:

  1. Получено принятое завершение соединения.
  2. Я создаю объект SSL с помощью SSL_new (ctx)
  3. Я создаю входящие и выходящие объекты BIO с помощью BIO_new (BIO_s_mem ()).
  4. Я установил BIO в объекте SSL, вызвав SSL_set_bio (ssl, bioIn, bioOut).
  5. Я вызываю SSL_set_accept_state (ssl), чтобы разрешить SSL_read и SSL_write вести переговоры.

Затем я перехожу к попытке разобраться с первым буфером данных, который был прочитан вызовом AcceptEx.

  1. Я вызываю BIO_Write (bioIn, buf, len), чтобы скопировать прочитанные данные в SSL.
  2. Затем я проверяю ожидающие данные о рукопожатии на bioOut, чтобы узнать, нужно ли их отправлять обратно клиенту. Однако, принимая новое соединение, я никогда не видел, чтобы в этот момент в bioOut были какие-либо данные.
  3. Затем я вызываю SSL_read (ssl, plainTextBuf, len), чтобы попытаться расшифровать данные, которые я поместил в bioIn на шаге 6. Это всегда возвращает -1, а SSL_get_error возвращает ERROR_SSL_WANT_READ. Насколько я понимаю, это означает, что у bioIn нет полной записи SSL, поэтому SSL требуется больше данных от клиента, прежде чем он сможет что-либо расшифровать.

Здесь я начинаю сталкиваться с проблемами, и именно здесь, я думаю, мне нужно какое-то направление. Я пробовал много вещей. Если в этот момент я повторно вызову SSL_read, он будет бесконечно возвращать ERROR_SSL_WANT_READ, предположительно потому, что использование памяти BIO фактически не обменивается данными через сокет для получения дополнительных данных. Следует ли мне отправить вызов WSARecv, чтобы дождаться дополнительных данных от клиента?

Я также попытался проверить буфер bioOut с помощью BIO_read на этом этапе, чтобы увидеть, есть ли данные, которые мне нужно отправить обратно клиенту. Действительно, они есть, и я отправляю их обратно с помощью WSASend, а также отправляю еще один вызов WSARecv, чтобы дождаться дополнительных данных (в ответ на мою отправку). Это приводит к получению дополнительных данных от клиента (WSARecv завершается после того, как отправка проходит), поэтому создается впечатление, что соединение продолжается. Однако, когда я обрабатываю это завершенное чтение, и SSL_read, и BIO_read возвращают ERROR_SSL_WANT_READ. Итак, у меня недостаточно данных для расшифровки полной записи, и мне нечего отправлять обратно клиенту. Отправка другого вызова WSARecv в ответ на эту ситуацию также не приводит к получению дополнительных данных от клиента. Я не знаю, что здесь нужно SSL.

Я сейчас застрял, но я буду пробовать еще кое-что. Я дополню этот вопрос комментариями, если что-нибудь выясню.


person Derek    schedule 14.12.2011    source источник


Ответы (1)


Вы запускаете новое перекрывающееся чтение в сокете, ожидаете его завершения, отправляете данные в свой BIO и повторяете шаги, которые вы делаете в настоящее время, снова.

ERROR_SSL_WANT_READ означает, что BIO требуется больше данных, т. Е. Требуется еще одно чтение.

В любой момент во время потока данных вам может потребоваться разрешить уровню SSL отправлять или получать больше данных, прежде чем вы сможете протолкнуть больше данных уровня приложения в BIO.

Мне казалось, что я достаточно подробно осветил все это в статье, на которую вы ссылаетесь; и код в этой статье был основой для кода, который я использую на моих собственных серверах на базе IOCP ...

person Len Holgate    schedule 17.12.2011
comment
У меня теперь все работает, Лен. Я не мог точно понять, что было не так с моим кодом, поэтому я отказался от части openssl и сделал еще один удар, более внимательно следя за структурой вашего образца кода. Спасибо, что разместили эту статью и образец кода. Это было очень полезно. - person Derek; 22.12.2011