我尝试在C中实现多线程客户端 - 服务器应用程序。这是我的连接特定代码:
服务器:
SSL_load_error_strings();
SSL_library_init();
OpenSSL_add_all_ciphers();
if((ctx->ssl_ctx = SSL_CTX_new(TLSv1_server_method())) == NULL) {
tproxy_error_die("unable to initialize SSLv3 methods", 1);
}
SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_ALL);
SSL_CTX_set_timeout(ctx->ssl_ctx, 300);
if(!SSL_CTX_use_certificate_chain_file(ctx->ssl_ctx, ctx->cert_bundle)) {
tproxy_error_die("unable to read certificate bundle file", 1);
}
if(strlen(ctx->key_file_pw)) {
SSL_CTX_set_default_passwd_cb(ctx->ssl_ctx, private_key_pass_callback);
SSL_CTX_set_default_passwd_cb_userdata(ctx->ssl_ctx, (void *)ctx);
}
if(!SSL_CTX_use_RSAPrivateKey_file(ctx->ssl_ctx, ctx->key_file, SSL_FILETYPE_PEM)) {
tproxy_error_die("unable to read key file", 1);
}
SSL_CTX_set_verify(ctx->ssl_ctx, SSL_VERIFY_NONE, NULL);
SSL_CTX_set_info_callback(ctx->ssl_ctx, apps_ssl_info_callback);
[...]
con->sock = accept(ctx->socket[i], (struct sockaddr *)&in_socket, &s_size);
/* make the accepted socket non-blocking */
if(ioctl(con->sock, FIONBIO, (char *)&enable) < 0) {
tproxy_error_die("cannot set socket flags", 1);
}
/* create a new SSL context to handle the connection with the peer */
con->ssl = SSL_new(ctx->ssl_ctx);
SSL_set_mode(con->ssl, SSL_MODE_AUTO_RETRY | SSL_MODE_ENABLE_PARTIAL_WRITE);
/* complete ssl connection */
con->sbio = BIO_new_socket(con->sock, BIO_NOCLOSE);
SSL_set_bio(con->ssl, con->sbio, con->sbio);
/* set chipher */
if (SSL_set_cipher_list(con->ssl,"AES128-SHA") <= 0) {
tproxy_error_die("unable to set chipher", 1);
}
/* do not require a valid client certificate */
SSL_set_verify(con->ssl, SSL_VERIFY_NONE, NULL);
后来我用SSL_read()和SSL_write()读取和写入(尊重-1作为返回代码必须导致评估SSL_get_error()并且我的结果在我的代码中重复相同的函数)。
然而,应用程序握手(客户端和服务器之间交换的几个字节)就像一个魅力。但是,一旦服务器向客户端发送超过4个字节(在应用程序握手之后),客户端似乎丢弃连接(SSL_read()返回0),即使服务器上的SSL_write确切地返回了我发送的字节数(SSL_ERROR_SYSCALL是SSL错误和系统错误保持0)。套接字没有关闭。
有没有人有线索 - 也许如何调试更多的openssl应用程序?
以下是来自客户端的msg_callback的输出:
SSL_connect:before/connect initialization
SSL_connect:SSLv3 write client hello A
SSL_connect:error in SSLv3 read server hello A
SSL_connect:SSLv3 read server hello A
SSL_connect:SSLv3 read server certificate A
SSL_connect:SSLv3 read server done A
SSL_connect:SSLv3 write client key exchange A
SSL_connect:SSLv3 write change cipher spec A
SSL_connect:SSLv3 write finished A
SSL_connect:SSLv3 flush data
SSL_connect:error in SSLv3 read server session ticket A
SSL_connect:SSLv3 read server session ticket A
SSL_connect:SSLv3 read finished A
---&GT;在这里关闭
以下是来自服务器的msg_callback的输出:
SSL_accept:before/accept initialization
SSL_accept:error in SSLv3 read client hello B
SSL_accept:SSLv3 read client hello B
SSL_accept:SSLv3 write server hello A
SSL_accept:SSLv3 write certificate A
SSL_accept:SSLv3 write server done A
SSL_accept:SSLv3 flush data
SSL_accept:error in SSLv3 read client certificate A
SSL_accept:error in SSLv3 read client certificate A
SSL_accept:error in SSLv3 read client certificate A
SSL_accept:error in SSLv3 read client certificate A
SSL_accept:error in SSLv3 read client certificate A
SSL_accept:error in SSLv3 read client certificate A
SSL_accept:error in SSLv3 read client certificate A
SSL_accept:error in SSLv3 read client certificate A
SSL_accept:error in SSLv3 read client certificate A
SSL_accept:error in SSLv3 read client certificate A
SSL_accept:SSLv3 read client key exchange A
SSL_accept:SSLv3 read finished A
SSL_accept:SSLv3 write session ticket A
SSL_accept:SSLv3 write change cipher spec A
SSL_accept:SSLv3 write finished A
SSL_accept:SSLv3 flush data
---&GT;在这里关闭
tcpdump告诉我,che tcp-fin首先来自客户端。但是如果服务器没有发送“kill”5个字节,则客户端可以通过ssl链路无限地发送应用程序keepalive消息。
在什么条件下,SSL_write能够以这种方式提醒对方,我该如何调试此行为?