原始套接字的api:
int sz;
ioctlsocket(sock, FIONREAD, &sz);
::recv(sock, buff, sz, 0);
ioctlsocket 可用于获取传入缓冲区大小,但如何使用openssl获取它:
int sz = what?
SSL_read(pSSL, buff, sz);
答案 0 :(得分:1)
但如何使用openssl获取[传入缓冲区大小]?
OpenSSL使用BIO
s。写缓冲区有BIO_get_write_buf_size
,但读缓冲区没有相应的控制。您可以使用BIO_set_read_buffer_size
设置读取缓冲区大小。但我相信为BIO
设置缓冲区,而不是套接字上的I / O缓冲区。请参阅struct bio_bio_st
中的crypto/bio/bss_bio.c
以及BIO_f_buffer(3)
和BIO_s_bio(3)
上的文档。
您应该可以在BIO_get_fd
上致电BIO
以获取基础套接字,然后使用ioctl
或ioctlsocket
。您可以在BIO
中找到SSL*
。 OpenSSL方便地有SSL_get_rbio
和SSL_get_wbio
。来自ssl/ssl.h
:
struct ssl_st
{
/* protocol version
* (one of SSL2_VERSION, SSL3_VERSION, TLS1_VERSION, DTLS1_VERSION)
*/
int version;
int type; /* SSL_ST_CONNECT or SSL_ST_ACCEPT */
const SSL_METHOD *method; /* SSLv3 */
/* There are 2 BIO's even though they are normally both the
* same. This is so data can be read and written to different
* handlers */
#ifndef OPENSSL_NO_BIO
BIO *rbio; /* used by SSL_read */
BIO *wbio; /* used by SSL_write */
BIO *bbio; /* used during session-id reuse to concatenate messages */
#else
char *rbio; /* used by SSL_read */
char *wbio; /* used by SSL_write */
char *bbio;
#endif
/* This holds a variable that indicates what we were doing
* when a 0 or -1 is returned. This is needed for
* non-blocking IO so we know what request needs re-doing when
* in SSL_accept or SSL_connect */
int rwstate;
...
};
答案 1 :(得分:0)
感谢jww代码和标题更正。
这是我的代码
// create ssl connection
ctx = SSL_CTX_new(SSLv23_client_method());
pSSL = SSL_new(ctx);
sbio = BIO_new_socket(raw_socket, BIO_NOCLOSE);
SSL_set_bio(pSSL, sbio, sbio);
SSL_set_fd(pSSL, raw_socket);
SSL_connect(pSSL)
// send
SSL_write(pSSL, s.c_str(), s.length());
// receive
int sock_fd;
int r = BIO_get_fd(sbio, &sock_fd); // <------------------
cout << r << endl; // output -2
甚至使用BIO_new_socket和SSL_set_fd中使用的 raw_socket
ulong sz = 0;
while(sz == 0) { // <--------- it loops forever, even server echoes data
if(ioctlsocket(raw_socket, FIONREAD, &sz) != 0) {
throw "get_recv_size";
}
Sleep(0);
}
raw_socket ,BIO中使用的底层套接字是不同的?
答案 2 :(得分:0)
OP基本上问到“缓冲区应该传递给SSL_read有多大?”建立jww的答案,并且 - 这是关键 - 如果您不介意使用可能在未来版本的OpenSSL中更改的内容,那么很容易获得读取缓冲区大小。
注意:这是基于openssl 1.0.2e
获取BIO,因为jww描述了使用SSL_get_rbio()。 BIO大小存储在BIO内的BIO_F_BUFFER_CTX中。这可以在文件crypto / bio / bf_cuff.c中找到:
static int buffer_new(BIO *bi)
{
BIO_F_BUFFER_CTX *ctx;
ctx = (BIO_F_BUFFER_CTX *)OPENSSL_malloc(sizeof(BIO_F_BUFFER_CTX));
if (ctx == NULL)
return (0);
ctx->ibuf = (char *)OPENSSL_malloc(DEFAULT_BUFFER_SIZE);
if (ctx->ibuf == NULL) {
OPENSSL_free(ctx);
return (0);
}
ctx->obuf = (char *)OPENSSL_malloc(DEFAULT_BUFFER_SIZE);
if (ctx->obuf == NULL) {
OPENSSL_free(ctx->ibuf);
OPENSSL_free(ctx);
return (0);
}
ctx->ibuf_size = DEFAULT_BUFFER_SIZE;
ctx->obuf_size = DEFAULT_BUFFER_SIZE;
ctx->ibuf_len = 0;
ctx->ibuf_off = 0;
ctx->obuf_len = 0;
ctx->obuf_off = 0;
bi->init = 1;
bi->ptr = (char *)ctx;
bi->flags = 0;
return (1);
}
获取读取缓冲区大小可以通过使用:
来完成((BIO_F_BUFFER_CTX*)bio->ptr)->ibuf_size;
其中 bio 是表示要查询的BIO的变量。 ptr 变量需要从char *转换回来。
请注意,这适用于任何BIO,例如从BIO_new_ssl_connect(ctx)返回的BIO等。