spdycat: Free fd and SSL object on error
This commit is contained in:
parent
50bff9e647
commit
817f35f3e4
210
src/spdycat.cc
210
src/spdycat.cc
|
@ -573,90 +573,10 @@ void print_stats(const SpdySession& spdySession)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int communicate(const std::string& host, uint16_t port,
|
int spdy_evloop(int fd, SSL *ssl, int spdy_version, SpdySession& spdySession,
|
||||||
SpdySession& spdySession,
|
const spdylay_session_callbacks *callbacks, int timeout)
|
||||||
const spdylay_session_callbacks *callbacks)
|
|
||||||
{
|
{
|
||||||
int rv;
|
int result = 0;
|
||||||
int timeout = config.timeout;
|
|
||||||
int fd = nonblock_connect_to(host, port, timeout);
|
|
||||||
if(fd == -1) {
|
|
||||||
std::cerr << "Could not connect to the host: " << spdySession.hostport
|
|
||||||
<< std::endl;
|
|
||||||
return -1;
|
|
||||||
} else if(fd == -2) {
|
|
||||||
std::cerr << "Request to " << spdySession.hostport << " timed out "
|
|
||||||
<< "during establishing connection."
|
|
||||||
<< std::endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if(set_tcp_nodelay(fd) == -1) {
|
|
||||||
std::cerr << "Setting TCP_NODELAY failed: " << strerror(errno)
|
|
||||||
<< std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string next_proto;
|
|
||||||
switch(config.spdy_version) {
|
|
||||||
case SPDYLAY_PROTO_SPDY2:
|
|
||||||
next_proto = "spdy/2";
|
|
||||||
break;
|
|
||||||
case SPDYLAY_PROTO_SPDY3:
|
|
||||||
next_proto = "spdy/3";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
SSL_CTX *ssl_ctx = 0;
|
|
||||||
SSL *ssl = 0;
|
|
||||||
if(!config.no_tls) {
|
|
||||||
ssl_ctx = SSL_CTX_new(TLSv1_client_method());
|
|
||||||
if(!ssl_ctx) {
|
|
||||||
std::cerr << ERR_error_string(ERR_get_error(), 0) << std::endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
setup_ssl_ctx(ssl_ctx, &next_proto);
|
|
||||||
if(!config.keyfile.empty()) {
|
|
||||||
if(SSL_CTX_use_PrivateKey_file(ssl_ctx, config.keyfile.c_str(),
|
|
||||||
SSL_FILETYPE_PEM) != 1) {
|
|
||||||
std::cerr << ERR_error_string(ERR_get_error(), 0) << std::endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!config.certfile.empty()) {
|
|
||||||
if(SSL_CTX_use_certificate_chain_file(ssl_ctx,
|
|
||||||
config.certfile.c_str()) != 1) {
|
|
||||||
std::cerr << ERR_error_string(ERR_get_error(), 0) << std::endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ssl = SSL_new(ssl_ctx);
|
|
||||||
if(!ssl) {
|
|
||||||
std::cerr << ERR_error_string(ERR_get_error(), 0) << std::endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (!SSL_set_tlsext_host_name(ssl, host.c_str())) {
|
|
||||||
std::cerr << ERR_error_string(ERR_get_error(), 0) << std::endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
rv = ssl_nonblock_handshake(ssl, fd, timeout);
|
|
||||||
if(rv == -1) {
|
|
||||||
return -1;
|
|
||||||
} else if(rv == -2) {
|
|
||||||
std::cerr << "Request to " << spdySession.hostport
|
|
||||||
<< " timed out in SSL/TLS handshake."
|
|
||||||
<< std::endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
spdySession.record_handshake_time();
|
|
||||||
int spdy_version = spdylay_npn_get_version(
|
|
||||||
reinterpret_cast<const unsigned char*>(next_proto.c_str()),
|
|
||||||
next_proto.size());
|
|
||||||
if (spdy_version <= 0) {
|
|
||||||
std::cerr << "No supported SPDY version was negotiated." << std::endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Spdylay sc(fd, ssl, spdy_version, callbacks, &spdySession);
|
Spdylay sc(fd, ssl, spdy_version, callbacks, &spdySession);
|
||||||
spdySession.sc = ≻
|
spdySession.sc = ≻
|
||||||
|
|
||||||
|
@ -678,7 +598,6 @@ int communicate(const std::string& host, uint16_t port,
|
||||||
pollfds[0].fd = fd;
|
pollfds[0].fd = fd;
|
||||||
ctl_poll(pollfds, &sc);
|
ctl_poll(pollfds, &sc);
|
||||||
|
|
||||||
bool ok = true;
|
|
||||||
timeval tv1, tv2;
|
timeval tv1, tv2;
|
||||||
while(!sc.finish()) {
|
while(!sc.finish()) {
|
||||||
if(config.timeout != -1) {
|
if(config.timeout != -1) {
|
||||||
|
@ -687,7 +606,8 @@ int communicate(const std::string& host, uint16_t port,
|
||||||
int nfds = poll(pollfds, npollfds, timeout);
|
int nfds = poll(pollfds, npollfds, timeout);
|
||||||
if(nfds == -1) {
|
if(nfds == -1) {
|
||||||
perror("poll");
|
perror("poll");
|
||||||
return -1;
|
result = -1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if(pollfds[0].revents & (POLLIN | POLLOUT)) {
|
if(pollfds[0].revents & (POLLIN | POLLOUT)) {
|
||||||
int rv;
|
int rv;
|
||||||
|
@ -697,13 +617,13 @@ int communicate(const std::string& host, uint16_t port,
|
||||||
std::cout << "reqnum=" << spdySession.reqvec.size()
|
std::cout << "reqnum=" << spdySession.reqvec.size()
|
||||||
<< ", completed=" << spdySession.complete << std::endl;
|
<< ", completed=" << spdySession.complete << std::endl;
|
||||||
}
|
}
|
||||||
ok = false;
|
result = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if((pollfds[0].revents & POLLHUP) || (pollfds[0].revents & POLLERR)) {
|
if((pollfds[0].revents & POLLHUP) || (pollfds[0].revents & POLLERR)) {
|
||||||
std::cout << "HUP" << std::endl;
|
std::cout << "HUP" << std::endl;
|
||||||
ok = false;
|
result = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(config.timeout != -1) {
|
if(config.timeout != -1) {
|
||||||
|
@ -712,11 +632,10 @@ int communicate(const std::string& host, uint16_t port,
|
||||||
if (timeout <= 0) {
|
if (timeout <= 0) {
|
||||||
std::cerr << "Requests to " << spdySession.hostport << " timed out."
|
std::cerr << "Requests to " << spdySession.hostport << " timed out."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
ok = false;
|
result = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert(ok);
|
|
||||||
ctl_poll(pollfds, &sc);
|
ctl_poll(pollfds, &sc);
|
||||||
}
|
}
|
||||||
if(!spdySession.all_requests_processed()) {
|
if(!spdySession.all_requests_processed()) {
|
||||||
|
@ -724,17 +643,120 @@ int communicate(const std::string& host, uint16_t port,
|
||||||
<< spdySession.reqvec.size()
|
<< spdySession.reqvec.size()
|
||||||
<< ", processed=" << spdySession.complete << std::endl;
|
<< ", processed=" << spdySession.complete << std::endl;
|
||||||
}
|
}
|
||||||
|
if(config.stat) {
|
||||||
|
print_stats(spdySession);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int communicate(const std::string& host, uint16_t port,
|
||||||
|
SpdySession& spdySession,
|
||||||
|
const spdylay_session_callbacks *callbacks)
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
int rv;
|
||||||
|
int spdy_version;
|
||||||
|
std::string next_proto;
|
||||||
|
int timeout = config.timeout;
|
||||||
|
SSL_CTX *ssl_ctx = 0;
|
||||||
|
SSL *ssl = 0;
|
||||||
|
int fd = nonblock_connect_to(host, port, timeout);
|
||||||
|
if(fd == -1) {
|
||||||
|
std::cerr << "Could not connect to the host: " << spdySession.hostport
|
||||||
|
<< std::endl;
|
||||||
|
result = -1;
|
||||||
|
goto fin;
|
||||||
|
} else if(fd == -2) {
|
||||||
|
std::cerr << "Request to " << spdySession.hostport << " timed out "
|
||||||
|
<< "during establishing connection."
|
||||||
|
<< std::endl;
|
||||||
|
result = -1;
|
||||||
|
goto fin;
|
||||||
|
}
|
||||||
|
if(set_tcp_nodelay(fd) == -1) {
|
||||||
|
std::cerr << "Setting TCP_NODELAY failed: " << strerror(errno)
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(config.spdy_version) {
|
||||||
|
case SPDYLAY_PROTO_SPDY2:
|
||||||
|
next_proto = "spdy/2";
|
||||||
|
break;
|
||||||
|
case SPDYLAY_PROTO_SPDY3:
|
||||||
|
next_proto = "spdy/3";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!config.no_tls) {
|
||||||
|
ssl_ctx = SSL_CTX_new(TLSv1_client_method());
|
||||||
|
if(!ssl_ctx) {
|
||||||
|
std::cerr << ERR_error_string(ERR_get_error(), 0) << std::endl;
|
||||||
|
result = -1;
|
||||||
|
goto fin;
|
||||||
|
}
|
||||||
|
setup_ssl_ctx(ssl_ctx, &next_proto);
|
||||||
|
if(!config.keyfile.empty()) {
|
||||||
|
if(SSL_CTX_use_PrivateKey_file(ssl_ctx, config.keyfile.c_str(),
|
||||||
|
SSL_FILETYPE_PEM) != 1) {
|
||||||
|
std::cerr << ERR_error_string(ERR_get_error(), 0) << std::endl;
|
||||||
|
result = -1;
|
||||||
|
goto fin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!config.certfile.empty()) {
|
||||||
|
if(SSL_CTX_use_certificate_chain_file(ssl_ctx,
|
||||||
|
config.certfile.c_str()) != 1) {
|
||||||
|
std::cerr << ERR_error_string(ERR_get_error(), 0) << std::endl;
|
||||||
|
result = -1;
|
||||||
|
goto fin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ssl = SSL_new(ssl_ctx);
|
||||||
|
if(!ssl) {
|
||||||
|
std::cerr << ERR_error_string(ERR_get_error(), 0) << std::endl;
|
||||||
|
result = -1;
|
||||||
|
goto fin;
|
||||||
|
}
|
||||||
|
if (!SSL_set_tlsext_host_name(ssl, host.c_str())) {
|
||||||
|
std::cerr << ERR_error_string(ERR_get_error(), 0) << std::endl;
|
||||||
|
result = -1;
|
||||||
|
goto fin;
|
||||||
|
}
|
||||||
|
rv = ssl_nonblock_handshake(ssl, fd, timeout);
|
||||||
|
if(rv == -1) {
|
||||||
|
result = -1;
|
||||||
|
goto fin;
|
||||||
|
} else if(rv == -2) {
|
||||||
|
std::cerr << "Request to " << spdySession.hostport
|
||||||
|
<< " timed out in SSL/TLS handshake."
|
||||||
|
<< std::endl;
|
||||||
|
result = -1;
|
||||||
|
goto fin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spdySession.record_handshake_time();
|
||||||
|
spdy_version = spdylay_npn_get_version(
|
||||||
|
reinterpret_cast<const unsigned char*>(next_proto.c_str()),
|
||||||
|
next_proto.size());
|
||||||
|
if (spdy_version <= 0) {
|
||||||
|
std::cerr << "No supported SPDY version was negotiated." << std::endl;
|
||||||
|
result = -1;
|
||||||
|
goto fin;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = spdy_evloop(fd, ssl, spdy_version, spdySession, callbacks, timeout);
|
||||||
|
fin:
|
||||||
if(ssl) {
|
if(ssl) {
|
||||||
SSL_shutdown(ssl);
|
SSL_shutdown(ssl);
|
||||||
SSL_free(ssl);
|
SSL_free(ssl);
|
||||||
SSL_CTX_free(ssl_ctx);
|
SSL_CTX_free(ssl_ctx);
|
||||||
}
|
}
|
||||||
shutdown(fd, SHUT_WR);
|
if(fd != -1) {
|
||||||
close(fd);
|
shutdown(fd, SHUT_WR);
|
||||||
if(config.stat) {
|
close(fd);
|
||||||
print_stats(spdySession);
|
|
||||||
}
|
}
|
||||||
return ok ? 0 : -1;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t file_read_callback
|
ssize_t file_read_callback
|
||||||
|
|
Loading…
Reference in New Issue