我遇到问题,我正在处理的程序在调用SSL_connect()后会立即关闭。我无法从中获取任何错误代码,因为之后调用SSL_get_error()将被忽略,因为它退出程序。如果我只是使用connect()执行正常的http请求,它可以正常工作。有人对此有任何想法吗?
我在Raspberry Pi 3上使用Raspbian运行它。 我是SSL的新手,所以任何指针都会非常感激。
编辑:这是我正在尝试做的代码片段
#include <openssl/ssl.h>
#include <iostream>
#include <resolv.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <string>
#include <unistd.h>
int main()
{
int sockfd;
struct addrinfo hints, *servinfo, *p;
int rv;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if ((rv = getaddrinfo("www.example.com", "https", &hints, &servinfo)) != 0)
{
fprintf(stderr, "getaddrinfo : %s\n", gai_strerror(rv));
exit(1);
}
SSL_load_error_strings();
SSL_library_init();
ssl_ctx = SSL_CTX_new(SSLv23_client_method());
SSL * connection = SSL_new(int sockfd;
struct addrinfo hints, *servinfo, *p;
int rv;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if ((rv = getaddrinfo("www.example.com", "https", &hints, &servinfo)) != 0)
{
fprintf(stderr, "getaddrinfo : %s\n", gai_strerror(rv));
exit(1);
}
SSL_load_error_strings();
SSL_library_init();
ssl_ctx = SSL_CTX_new(SSLv23_client_method());
SSL * connection = SSL_new(ssl_ctx);
for (p = servinfo; p != NULL; p = p->ai_next)
{
if ((sockfd = socket(p->ai_family, p->ai_socktype,
p->ai_protocol)) == -1)
{
perror("socket");
continue;
}
int fd = SSL_set_fd(connection, sockfd);
break;
}
if (p == NULL)
{
// looped off the end of the list with no connection
fprintf(stderr, "failed to connect\n");
exit(2);
}
int connRet = 0;
while(connRet != 1 )
{
connRet = SSL_connect(connection);
cout << "Error : " << SSL_get_error(connection, connRet) << endl;
}
freeaddrinfo(servinfo);
return 0;
}
编辑2:终于设法通过调试器运行它,现在我得到了:
(程序退出代码:141) 按返回继续
根据这个问题:socket connection getting closed abruptly with code 141是一个SIGPIPE信号。
答案 0 :(得分:3)
不确定导致崩溃的原因,但SSL_connect
不等同于connect
:它会在已建立的连接上启动TLS / SSL握手。由于sockfd
未在您的代码中连接,因此会失败并将connRet
设置为-1,从而导致无限循环。
您应该在创建套接字后立即连接套接字,然后再启动SSL握手:
if ((sockfd = socket(p->ai_family, p->ai_socktype,
p->ai_protocol)) == -1)
{
perror("socket");
continue;
}
/* connect at the TCP level */
if (connect(sockfd, servinfo->ai_addr, servinfo->ai_addrlen)) {
perror("connect");
continue;
}
int fd = SSL_set_fd(connection, sockfd);
...
但无论如何,您应该控制程序以删除可能的无限循环,并在错误消息中保持一致:使用C ++流cout
或C FILE * stderr
。如果可以打开套接字,最好正确关闭套接字。