summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFedor Indutny <fedor@indutny.com>2015-04-26 14:26:57 +0200
committerFedor Indutny <fedor@indutny.com>2015-04-30 11:01:56 +0200
commit2d241b3b82d246881c8a6bcc7148d59349309d5f (patch)
tree21043729dee6476b0e7aa69011fac05e3e4b216e /src
parent73062521a424614fccfe6399b47030ee065e1977 (diff)
downloadandroid-node-v8-2d241b3b82d246881c8a6bcc7148d59349309d5f.tar.gz
android-node-v8-2d241b3b82d246881c8a6bcc7148d59349309d5f.tar.bz2
android-node-v8-2d241b3b82d246881c8a6bcc7148d59349309d5f.zip
tls: destroy SSL once it is out of use
Do not keep SSL structure in memory once socket is closed. This should lower the memory usage in many cases. Fix: https://github.com/iojs/io.js/issues/1522 PR-URL: https://github.com/iojs/io.js/pull/1529 Reviewed-By: Shigeki Ohtsu <ohtsu@iij.ad.jp>
Diffstat (limited to 'src')
-rw-r--r--src/node_crypto.cc11
-rw-r--r--src/node_crypto.h7
-rw-r--r--src/tls_wrap.cc39
-rw-r--r--src/tls_wrap.h1
4 files changed, 49 insertions, 9 deletions
diff --git a/src/node_crypto.cc b/src/node_crypto.cc
index 04b50361ba..1a7388bea0 100644
--- a/src/node_crypto.cc
+++ b/src/node_crypto.cc
@@ -131,6 +131,7 @@ template int SSLWrap<TLSWrap>::SelectNextProtoCallback(
void* arg);
#endif
template int SSLWrap<TLSWrap>::TLSExtStatusCallback(SSL* s, void* arg);
+template void SSLWrap<TLSWrap>::DestroySSL();
static void crypto_threadid_cb(CRYPTO_THREADID* tid) {
@@ -1871,6 +1872,16 @@ void SSLWrap<Base>::SSLGetter(Local<String> property,
}
+template <class Base>
+void SSLWrap<Base>::DestroySSL() {
+ if (ssl_ == nullptr)
+ return;
+
+ SSL_free(ssl_);
+ ssl_ = nullptr;
+}
+
+
void Connection::OnClientHelloParseEnd(void* arg) {
Connection* conn = static_cast<Connection*>(arg);
diff --git a/src/node_crypto.h b/src/node_crypto.h
index 75ffe4f31d..8fec4bb625 100644
--- a/src/node_crypto.h
+++ b/src/node_crypto.h
@@ -144,10 +144,7 @@ class SSLWrap {
}
virtual ~SSLWrap() {
- if (ssl_ != nullptr) {
- SSL_free(ssl_);
- ssl_ = nullptr;
- }
+ DestroySSL();
if (next_sess_ != nullptr) {
SSL_SESSION_free(next_sess_);
next_sess_ = nullptr;
@@ -221,6 +218,8 @@ class SSLWrap {
static void SSLGetter(v8::Local<v8::String> property,
const v8::PropertyCallbackInfo<v8::Value>& info);
+ void DestroySSL();
+
inline Environment* ssl_env() const {
return env_;
}
diff --git a/src/tls_wrap.cc b/src/tls_wrap.cc
index c774a8490b..c013bf935e 100644
--- a/src/tls_wrap.cc
+++ b/src/tls_wrap.cc
@@ -208,7 +208,7 @@ void TLSWrap::Receive(const FunctionCallbackInfo<Value>& args) {
uv_buf_t buf;
// Copy given buffer entirely or partiall if handle becomes closed
- while (len > 0 && !wrap->IsClosing()) {
+ while (len > 0 && wrap->IsAlive() && !wrap->IsClosing()) {
wrap->stream_->OnAlloc(len, &buf);
size_t copy = buf.len > len ? len : buf.len;
memcpy(buf.base, data, copy);
@@ -282,6 +282,9 @@ void TLSWrap::EncOut() {
if (established_ && !write_item_queue_.IsEmpty())
MakePending();
+ if (ssl_ == nullptr)
+ return;
+
// No data to write
if (BIO_pending(enc_out_) == 0) {
if (clear_in_->Length() == 0)
@@ -396,7 +399,8 @@ void TLSWrap::ClearOut() {
if (eof_)
return;
- CHECK_NE(ssl_, nullptr);
+ if (ssl_ == nullptr)
+ return;
char out[kClearOutChunkSize];
int read;
@@ -451,6 +455,9 @@ bool TLSWrap::ClearIn() {
if (!hello_parser_.IsEnded())
return false;
+ if (ssl_ == nullptr)
+ return false;
+
int written = 0;
while (clear_in_->Length() > 0) {
size_t avail = 0;
@@ -503,7 +510,7 @@ int TLSWrap::GetFD() {
bool TLSWrap::IsAlive() {
- return stream_->IsAlive();
+ return ssl_ != nullptr && stream_->IsAlive();
}
@@ -573,6 +580,9 @@ int TLSWrap::DoWrite(WriteWrap* w,
return 0;
}
+ if (ssl_ == nullptr)
+ return UV_EPROTO;
+
int written = 0;
for (i = 0; i < count; i++) {
written = SSL_write(ssl_, bufs[i].base, bufs[i].len);
@@ -660,7 +670,10 @@ void TLSWrap::DoRead(ssize_t nread,
}
// Only client connections can receive data
- CHECK_NE(ssl_, nullptr);
+ if (ssl_ == nullptr) {
+ OnRead(UV_EPROTO, nullptr);
+ return;
+ }
// Commit read data
NodeBIO* enc_in = NodeBIO::FromBIO(enc_in_);
@@ -680,7 +693,7 @@ void TLSWrap::DoRead(ssize_t nread,
int TLSWrap::DoShutdown(ShutdownWrap* req_wrap) {
- if (SSL_shutdown(ssl_) == 0)
+ if (ssl_ != nullptr && SSL_shutdown(ssl_) == 0)
SSL_shutdown(ssl_);
shutdown_ = true;
EncOut();
@@ -696,6 +709,9 @@ void TLSWrap::SetVerifyMode(const FunctionCallbackInfo<Value>& args) {
if (args.Length() < 2 || !args[0]->IsBoolean() || !args[1]->IsBoolean())
return env->ThrowTypeError("Bad arguments, expected two booleans");
+ if (wrap->ssl_ == nullptr)
+ return env->ThrowTypeError("SetVerifyMode after destroySSL");
+
int verify_mode;
if (wrap->is_server()) {
bool request_cert = args[0]->IsTrue();
@@ -735,6 +751,14 @@ void TLSWrap::EnableHelloParser(const FunctionCallbackInfo<Value>& args) {
}
+void TLSWrap::DestroySSL(const FunctionCallbackInfo<Value>& args) {
+ TLSWrap* wrap = Unwrap<TLSWrap>(args.Holder());
+ wrap->SSLWrap<TLSWrap>::DestroySSL();
+ delete wrap->clear_in_;
+ wrap->clear_in_ = nullptr;
+}
+
+
void TLSWrap::OnClientHelloParseEnd(void* arg) {
TLSWrap* c = static_cast<TLSWrap*>(arg);
c->Cycle();
@@ -747,6 +771,8 @@ void TLSWrap::GetServername(const FunctionCallbackInfo<Value>& args) {
TLSWrap* wrap = Unwrap<TLSWrap>(args.Holder());
+ CHECK_NE(wrap->ssl_, nullptr);
+
const char* servername = SSL_get_servername(wrap->ssl_,
TLSEXT_NAMETYPE_host_name);
if (servername != nullptr) {
@@ -771,6 +797,8 @@ void TLSWrap::SetServername(const FunctionCallbackInfo<Value>& args) {
if (!wrap->is_client())
return;
+ CHECK_NE(wrap->ssl_, nullptr);
+
#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
node::Utf8Value servername(env->isolate(), args[0].As<String>());
SSL_set_tlsext_host_name(wrap->ssl_, *servername);
@@ -830,6 +858,7 @@ void TLSWrap::Initialize(Handle<Object> target,
env->SetProtoMethod(t, "setVerifyMode", SetVerifyMode);
env->SetProtoMethod(t, "enableSessionCallbacks", EnableSessionCallbacks);
env->SetProtoMethod(t, "enableHelloParser", EnableHelloParser);
+ env->SetProtoMethod(t, "destroySSL", DestroySSL);
StreamBase::AddMethods<TLSWrap>(env, t, StreamBase::kFlagHasWritev);
SSLWrap<TLSWrap>::AddMethods(env, t);
diff --git a/src/tls_wrap.h b/src/tls_wrap.h
index 9f095355bb..25088d3026 100644
--- a/src/tls_wrap.h
+++ b/src/tls_wrap.h
@@ -132,6 +132,7 @@ class TLSWrap : public crypto::SSLWrap<TLSWrap>,
const v8::FunctionCallbackInfo<v8::Value>& args);
static void EnableHelloParser(
const v8::FunctionCallbackInfo<v8::Value>& args);
+ static void DestroySSL(const v8::FunctionCallbackInfo<v8::Value>& args);
#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
static void GetServername(const v8::FunctionCallbackInfo<v8::Value>& args);