OpenSSL SSL_shutdown получил сигнал SIGPIPE, сломанный канал

Я пишу клиент http/https, используя openssl-0.9.8e

Я получаю сообщение об ошибке, когда звоню SSL_read()

затем я вызываю SSL_get_error, получаю SSL_ERROR_SYSCALL и ошибаюсь ECONNRESET 104 /* Connection reset by peer */

в соответствии с документацией SSL это означает:

 SSL_ERROR_SYSCALL

 Some I/O error occurred. The OpenSSL error queue may contain more information on the error. 
If the error queue is empty (i.e. ERR_get_error() returns 0), ret can be used to find out more about the
    error: If ret == 0, an EOF was observed that violates the protocol. If ret == -1, the underlying BIO
    reported an I/O error (for socket I/O on Unix systems, consult errno for details).

Ну, соединение сброшено, я звоню SSL_shutdown, чтобы закрыть соединение, о, Program received signal SIGPIPE, Broken pipe.

Боже, я звоню signal(SIGPIPE, SIG_IGN);, чтобы проигнорировать сигнал "SIGPIPE", но, кажется, это не работает~

Произошла ошибка сегментации

#0  0x00000032bd00d96b in write () from /lib64/libpthread.so.0
#1  0x0000003add478367 in ?? () from /lib64/libcrypto.so.6
#2  0x0000003add4766fe in BIO_write () from /lib64/libcrypto.so.6
#3  0x0000003add8208fd in ssl3_write_pending () from /lib64/libssl.so.6
#4  0x0000003add820d9a in ssl3_dispatch_alert () from /lib64/libssl.so.6
#5  0x0000003add81e982 in ssl3_shutdown () from /lib64/libssl.so.6
#6  0x00000000004565d0 in CWsPollUrl::SSLClear (this=<value optimized out>, ctx=0x2aaab804a1b0, ssl=0x2aaab804a680)
    at ../src/Wspoll.cpp:1122
#7  0x00000000004575e0 in CWsPollUrl::asyncEventDelete (this=0x4d422e50, eev=0x2aaab8001160) at ../src/Wspoll.cpp:1546
#8  0x000000000045928a in CWsPollUrl::onFail (this=0x4d422e50, eev=0x2aaab8001160, errorCode=4) at ../src/Wspoll.cpp:1523
#9  0x000000000045ab17 in CWsPollUrl::handleData (this=0x4d422e50, eev=0x2aaab8001160, len=<value optimized out>) at ../src/Wspoll.cpp:1259
#10 0x000000000045abcc in CWsPollUrl::asyncRecvEvent (this=0x4d422e50, fd=<value optimized out>, eev=0x2aaab8001160)
    at ../src/Wspoll.cpp:1211
#11 0x00000000004636b5 in event_base_loop (base=0x14768360, flags=0) at event.c:1350
#12 0x0000000000456a62 in CWsPollUrl::run (this=<value optimized out>, param=<value optimized out>) at ../src/Wspoll.cpp:461
#13 0x0000000000436c5c in doPollUrl (data=<value optimized out>, user_data=<value optimized out>) at ../src/PollStrategy.cpp:151
#14 0x00000032bf44a95d in ?? () from /lib64/libglib-2.0.so.0
#15 0x00000032bf448e04 in ?? () from /lib64/libglib-2.0.so.0
#16 0x00000032bd00677d in start_thread () from /lib64/libpthread.so.0
#17 0x00000032bc4d3c1d in clone () from /lib64/libc.so.6

почему я получаю сигнал SIGPIPE, я уже позвонил signal(SIGPIPE, SIG_IGN); Кто-нибудь знает, почему?

заранее спасибо


person user3282867    schedule 23.03.2014    source источник
comment
Если при чтении вы получаете сообщение об ошибке, отличной от тайм-аута, вы почти наверняка имеете дело с уже разорванным соединением. Любые последующие ошибки, которые вы можете получить, вероятно, следует игнорировать.   -  person user207421    schedule 23.03.2014
comment
Вы уверены, что действительно вызывали signal(SIGPIPE, SIG_IGN); в этом процессе? Если вы вызвали его до fork и exec, он может быть сброшен. Также кажется бесполезным правильно завершать соединение, которое было прервано узлом.   -  person Marian    schedule 23.03.2014


Ответы (1)


Если вы получаете ошибку ввода-вывода с SSL_read, нет особого смысла вызывать SSL_shutdown, потому что завершение работы пытается отправить уведомление об отключении «закрыть уведомление» узлу, и это, очевидно, не будет работать при разрыве соединения. Поэтому вы получаете SIGPIPE или EPIPE. Получение ECONNRESET из SSL_read в этом случае, вероятно, означает, что клиент жестко закрыл соединение, например. без выполнения SSL_shutdown. Вы не должны продолжать работу с сокетом после ошибки, т.е. даже не выполняя SSL_shutdown.

person Steffen Ullrich    schedule 23.03.2014