Skip to content

Commit

Permalink
added error callback and curve error codes
Browse files Browse the repository at this point in the history
  • Loading branch information
burilovmv committed Jul 7, 2017
1 parent 30ab0ed commit 0ad0978
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 9 deletions.
14 changes: 14 additions & 0 deletions include/zmq.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,16 @@ extern "C" {
#define ETERM (ZMQ_HAUSNUMERO + 53)
#define EMTHREAD (ZMQ_HAUSNUMERO + 54)

// Curve error codes
#define ECURVEKEY (ZMQ_HAUSNUMERO + 55) // possibly wrong server key
#define ECURVEHANDSHAKE (ZMQ_HAUSNUMERO + 56) // invalid handshake command
#define ECURVECLIENT (ZMQ_HAUSNUMERO + 57) // invalid curve client
#define ECURVENONCE (ZMQ_HAUSNUMERO + 58) // wrong nonce
#define ECURVEHELLOVER (ZMQ_HAUSNUMERO + 59) // wrong hello version
#define ECURVEHELLOSIZE (ZMQ_HAUSNUMERO + 60) // wrong hello size
#define ECURVEHELLOCMD (ZMQ_HAUSNUMERO + 61) // wrong hello command


/* This function retrieves the errno as it is known to 0MQ library. The goal */
/* of this function is to make the code 100% portable, including where 0MQ */
/* compiled with certain CRT library (on Windows) is linked to an */
Expand All @@ -202,6 +212,10 @@ ZMQ_EXPORT const char *zmq_strerror (int errnum);
/* Run-time API version detection */
ZMQ_EXPORT void zmq_version (int *major, int *minor, int *patch);

/* Error handler callback */
typedef void(*zmq_error_fn) (int err, const char* host, void* data);
ZMQ_EXPORT int zmq_error_handler(void* context, zmq_error_fn ffn);

/******************************************************************************/
/* 0MQ infrastructure (a.k.a. context) initialisation & termination. */
/******************************************************************************/
Expand Down
14 changes: 14 additions & 0 deletions src/ctx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ int clipped_maxsocket (int max_requested)

zmq::ctx_t::ctx_t () :
tag (ZMQ_CTX_TAG_VALUE_GOOD),
error_fn(0),
starting (true),
terminating (false),
reaper (NULL),
Expand Down Expand Up @@ -107,6 +108,19 @@ bool zmq::ctx_t::check_tag ()
return tag == ZMQ_CTX_TAG_VALUE_GOOD;
}

void zmq::ctx_t::set_error_handler(zmq_error_fn ffn)
{
error_fn = ffn;
}

void zmq::ctx_t::handle_error(int errno_, const char* host)
{
if(error_fn)
{
error_fn(errno_, host, NULL);
}
}

zmq::ctx_t::~ctx_t ()
{
// Check that there are no remaining sockets.
Expand Down
9 changes: 9 additions & 0 deletions src/ctx.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ namespace zmq
// Returns false if object is not a context.
bool check_tag ();

// set error handler callback
void set_error_handler(zmq_error_fn ffn);

// redirects error to error handler callback if it is set
void handle_error(int errno_, const char* host);

// This function is called when user invokes zmq_ctx_term. If there are
// no more sockets open it'll cause all the infrastructure to be shut
// down. If there are open sockets still, the deallocation happens
Expand Down Expand Up @@ -145,6 +151,9 @@ namespace zmq
// Used to check whether the object is a context.
uint32_t tag;

// Error handler callback
zmq_error_fn error_fn;

// Sockets belonging to this context. We need the list so that
// we can notify the sockets when zmq_ctx_term() is called.
// The sockets will return ETERM then.
Expand Down
18 changes: 9 additions & 9 deletions src/curve_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ int zmq::curve_server_t::process_handshake_command (msg_t *msg_)
default:
// Temporary support for security debugging
puts ("CURVE I: invalid handshake command");
errno = EPROTO;
errno = ECURVEHANDSHAKE;
rc = -1;
break;
}
Expand Down Expand Up @@ -175,15 +175,15 @@ int zmq::curve_server_t::decode (msg_t *msg_)
if (msg_->size () < 33) {
// Temporary support for security debugging
puts ("CURVE I: invalid CURVE client, sent malformed command");
errno = EPROTO;
errno = ECURVECLIENT;
return -1;
}

const uint8_t *message = static_cast <uint8_t *> (msg_->data ());
if (memcmp (message, "\x07MESSAGE", 8)) {
// Temporary support for security debugging
puts ("CURVE I: invalid CURVE client, did not send MESSAGE");
errno = EPROTO;
errno = ECURVECLIENT;
return -1;
}

Expand All @@ -192,7 +192,7 @@ int zmq::curve_server_t::decode (msg_t *msg_)
memcpy (message_nonce + 16, message + 8, 8);
uint64_t nonce = get_uint64(message + 8);
if (nonce <= cn_peer_nonce) {
errno = EPROTO;
errno = ECURVENONCE;
return -1;
}
cn_peer_nonce = nonce;
Expand Down Expand Up @@ -231,7 +231,7 @@ int zmq::curve_server_t::decode (msg_t *msg_)
else {
// Temporary support for security debugging
puts ("CURVE I: connection key used for MESSAGE is wrong");
errno = EPROTO;
errno = ECURVEKEY;
}
free (message_plaintext);
free (message_box);
Expand Down Expand Up @@ -269,15 +269,15 @@ int zmq::curve_server_t::process_hello (msg_t *msg_)
if (msg_->size () != 200) {
// Temporary support for security debugging
puts ("CURVE I: client HELLO is not correct size");
errno = EPROTO;
errno = ECURVEHELLOSIZE;
return -1;
}

const uint8_t * const hello = static_cast <uint8_t *> (msg_->data ());
if (memcmp (hello, "\x05HELLO", 6)) {
// Temporary support for security debugging
puts ("CURVE I: client HELLO has invalid command name");
errno = EPROTO;
errno = ECURVEHELLOCMD;
return -1;
}

Expand All @@ -287,7 +287,7 @@ int zmq::curve_server_t::process_hello (msg_t *msg_)
if (major != 1 || minor != 0) {
// Temporary support for security debugging
puts ("CURVE I: client HELLO has unknown version number");
errno = EPROTO;
errno = ECURVEHELLOVER;
return -1;
}

Expand All @@ -312,7 +312,7 @@ int zmq::curve_server_t::process_hello (msg_t *msg_)
if (rc != 0) {
// Temporary support for security debugging
puts ("CURVE I: cannot open client HELLO -- wrong server key?");
errno = EPROTO;
errno = ECURVEKEY;
return -1;
}

Expand Down
2 changes: 2 additions & 0 deletions src/stream_engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -965,6 +965,8 @@ int zmq::stream_engine_t::push_one_then_decode_and_push (msg_t *msg_)

void zmq::stream_engine_t::error (error_reason_t reason)
{
socket->get_ctx()->handle_error(errno, peer_address.c_str());

if (options.raw_socket && options.raw_notify) {
// For raw sockets, send a final 0-length message to the application
// so that it knows the peer has been disconnected.
Expand Down
12 changes: 12 additions & 0 deletions src/zmq.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,18 @@ int zmq_errno (void)
}


int zmq_error_handler(void* ctx_, zmq_error_fn ffn)
{
if (!ctx_ || !((zmq::ctx_t *) ctx_)->check_tag()) {
errno = EFAULT;
return -1;
}

((zmq::ctx_t *) ctx_)->set_error_handler(ffn);

return 0;
}

// New context API

void *zmq_ctx_new (void)
Expand Down

0 comments on commit 0ad0978

Please sign in to comment.