Unverified Commit 810d3b43 authored by Luca Boccassi's avatar Luca Boccassi Committed by GitHub

Merge pull request #3703 from somdoron/ws_mechanism

problem: wss transport return incorrect return code for error
parents 8d9acb72 a9bb5264
...@@ -354,7 +354,7 @@ void zmq::stream_engine_base_t::out_event () ...@@ -354,7 +354,7 @@ void zmq::stream_engine_base_t::out_event ()
// If there is no data to send, stop polling for output. // If there is no data to send, stop polling for output.
if (_outsize == 0) { if (_outsize == 0) {
_output_stopped = true; _output_stopped = true;
reset_pollout (_handle); reset_pollout ();
return; return;
} }
} }
...@@ -370,7 +370,7 @@ void zmq::stream_engine_base_t::out_event () ...@@ -370,7 +370,7 @@ void zmq::stream_engine_base_t::out_event ()
// The engine is not terminated until we detect input error; // The engine is not terminated until we detect input error;
// this is necessary to prevent losing incoming messages. // this is necessary to prevent losing incoming messages.
if (nbytes == -1) { if (nbytes == -1) {
reset_pollout (_handle); reset_pollout ();
return; return;
} }
...@@ -381,7 +381,7 @@ void zmq::stream_engine_base_t::out_event () ...@@ -381,7 +381,7 @@ void zmq::stream_engine_base_t::out_event ()
// to send, stop polling for output. // to send, stop polling for output.
if (unlikely (_handshaking)) if (unlikely (_handshaking))
if (_outsize == 0) if (_outsize == 0)
reset_pollout (_handle); reset_pollout ();
} }
void zmq::stream_engine_base_t::restart_output () void zmq::stream_engine_base_t::restart_output ()
......
...@@ -102,6 +102,7 @@ class stream_engine_base_t : public io_object_t, public i_engine ...@@ -102,6 +102,7 @@ class stream_engine_base_t : public io_object_t, public i_engine
virtual int read (void *data, size_t size_); virtual int read (void *data, size_t size_);
virtual int write (const void *data_, size_t size_); virtual int write (const void *data_, size_t size_);
void reset_pollout () { io_object_t::reset_pollout (_handle); }
void set_pollout () { io_object_t::set_pollout (_handle); } void set_pollout () { io_object_t::set_pollout (_handle); }
void set_pollin () { io_object_t::set_pollin (_handle); } void set_pollin () { io_object_t::set_pollin (_handle); }
session_base_t *session () { return _session; } session_base_t *session () { return _session; }
......
...@@ -128,21 +128,53 @@ void zmq::wss_engine_t::plug_internal () ...@@ -128,21 +128,53 @@ void zmq::wss_engine_t::plug_internal ()
in_event (); in_event ();
} }
void zmq::wss_engine_t::out_event ()
{
if (_established)
return ws_engine_t::out_event ();
int rc = gnutls_handshake (_tls_session);
reset_pollout ();
if (rc == GNUTLS_E_SUCCESS) {
start_ws_handshake ();
_established = true;
return;
} else if (rc == GNUTLS_E_AGAIN) {
int direction = gnutls_record_get_direction (_tls_session);
if (direction == 1)
set_pollout ();
return;
} else if (rc == GNUTLS_E_INTERRUPTED
|| rc == GNUTLS_E_WARNING_ALERT_RECEIVED) {
return;
} else {
error (zmq::i_engine::connection_error);
return;
}
}
bool zmq::wss_engine_t::handshake () bool zmq::wss_engine_t::handshake ()
{ {
if (!_established) { if (!_established) {
int rc = gnutls_handshake (_tls_session); int rc = gnutls_handshake (_tls_session);
// TODO: when E_AGAIN is returned we might need to call gnutls_handshake for out_event as well, see gnutls_record_get_direction
if (rc == GNUTLS_E_SUCCESS) { if (rc == GNUTLS_E_SUCCESS) {
start_ws_handshake (); start_ws_handshake ();
_established = true; _established = true;
return false; return false;
} else if (rc == GNUTLS_E_AGAIN || rc == GNUTLS_E_INTERRUPTED } else if (rc == GNUTLS_E_AGAIN) {
|| rc == GNUTLS_E_WARNING_ALERT_RECEIVED) int direction = gnutls_record_get_direction (_tls_session);
if (direction == 1)
set_pollout ();
return false;
} else if (rc == GNUTLS_E_INTERRUPTED
|| rc == GNUTLS_E_WARNING_ALERT_RECEIVED) {
return false; return false;
else { } else {
error (zmq::i_engine::connection_error); error (zmq::i_engine::connection_error);
return false; return false;
} }
...@@ -171,6 +203,11 @@ int zmq::wss_engine_t::read (void *data_, size_t size_) ...@@ -171,6 +203,11 @@ int zmq::wss_engine_t::read (void *data_, size_t size_)
return -1; return -1;
} }
if (rc < 0) {
errno = EINVAL;
return -1;
}
// TODO: change return type to ssize_t (signed) // TODO: change return type to ssize_t (signed)
return rc; return rc;
} }
...@@ -189,6 +226,11 @@ int zmq::wss_engine_t::write (const void *data_, size_t size_) ...@@ -189,6 +226,11 @@ int zmq::wss_engine_t::write (const void *data_, size_t size_)
return -1; return -1;
} }
if (rc < 0) {
errno = EINVAL;
return -1;
}
// TODO: change return type to ssize_t (signed) // TODO: change return type to ssize_t (signed)
return rc; return rc;
} }
...@@ -49,6 +49,8 @@ class wss_engine_t : public ws_engine_t ...@@ -49,6 +49,8 @@ class wss_engine_t : public ws_engine_t
const char *hostname_); const char *hostname_);
~wss_engine_t (); ~wss_engine_t ();
void out_event ();
protected: protected:
bool handshake (); bool handshake ();
void plug_internal (); void plug_internal ();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment