Commit ec943ac5 authored by Ian Barber's avatar Ian Barber

Merge pull request #590 from hurtonm/master

Refactor how properties are parsed
parents 19cf076f 99d49745
...@@ -399,47 +399,16 @@ int zmq::curve_client_t::process_ready (msg_t *msg_) ...@@ -399,47 +399,16 @@ int zmq::curve_client_t::process_ready (msg_t *msg_)
return -1; return -1;
} }
rc = parse_property_list (ready_plaintext + crypto_box_ZEROBYTES, rc = parse_properties (ready_plaintext + crypto_box_ZEROBYTES,
clen - crypto_box_ZEROBYTES); clen - crypto_box_ZEROBYTES);
return rc; return rc;
} }
int zmq::curve_client_t::parse_property_list (const uint8_t *ptr, int zmq::curve_client_t::property (const std::string name,
size_t bytes_left) const void *value, size_t length)
{ {
while (bytes_left > 1) { if (name == "Socket-Type") {
const size_t name_length = static_cast <size_t> (*ptr); // TODO: Implement socket type checking
ptr += 1;
bytes_left -= 1;
if (bytes_left < name_length)
break;
const std::string name = std::string ((const char *) ptr, name_length);
ptr += name_length;
bytes_left -= name_length;
if (bytes_left < 4)
break;
const size_t value_length = static_cast <size_t> (get_uint32 (ptr));
ptr += 4;
bytes_left -= 4;
if (bytes_left < value_length)
break;
const uint8_t * const value = ptr;
ptr += value_length;
bytes_left -= value_length;
if (name == "Socket-Type") {
// TODO: Implement socket type checking
}
else
if (name == "Identity" && options.recv_identity)
set_peer_identity (value, value_length);
}
if (bytes_left > 0) {
errno = EPROTO;
return -1;
} }
return 0; return 0;
} }
......
...@@ -101,7 +101,8 @@ namespace zmq ...@@ -101,7 +101,8 @@ namespace zmq
int initiate_msg (msg_t *msg_); int initiate_msg (msg_t *msg_);
int process_ready (msg_t *msg_); int process_ready (msg_t *msg_);
int parse_property_list (const uint8_t *ptr, size_t length); virtual int property (const std::string name,
const void *value, size_t length);
}; };
} }
......
...@@ -441,8 +441,8 @@ int zmq::curve_server_t::process_initiate (msg_t *msg_) ...@@ -441,8 +441,8 @@ int zmq::curve_server_t::process_initiate (msg_t *msg_)
} }
} }
return parse_property_list (initiate_plaintext + crypto_box_ZEROBYTES + 96, return parse_properties (initiate_plaintext + crypto_box_ZEROBYTES + 96,
clen - crypto_box_ZEROBYTES - 96); clen - crypto_box_ZEROBYTES - 96);
} }
int zmq::curve_server_t::ready_msg (msg_t *msg_) int zmq::curve_server_t::ready_msg (msg_t *msg_)
...@@ -543,42 +543,11 @@ void zmq::curve_server_t::send_zap_request (const uint8_t *key) ...@@ -543,42 +543,11 @@ void zmq::curve_server_t::send_zap_request (const uint8_t *key)
errno_assert (rc == 0); errno_assert (rc == 0);
} }
int zmq::curve_server_t::parse_property_list (const uint8_t *ptr, int zmq::curve_server_t::property (const std::string name,
size_t bytes_left) const void *value, size_t length)
{ {
while (bytes_left > 1) { if (name == "Socket-Type") {
const size_t name_length = static_cast <size_t> (*ptr); // TODO: Implement socket type checking
ptr += 1;
bytes_left -= 1;
if (bytes_left < name_length)
break;
const std::string name = std::string ((const char *) ptr, name_length);
ptr += name_length;
bytes_left -= name_length;
if (bytes_left < 4)
break;
const size_t value_length = static_cast <size_t> (get_uint32 (ptr));
ptr += 4;
bytes_left -= 4;
if (bytes_left < value_length)
break;
const uint8_t * const value = ptr;
ptr += value_length;
bytes_left -= value_length;
if (name == "Socket-Type") {
// TODO: Implement socket type checking
}
else
if (name == "Identity" && options.recv_identity)
set_peer_identity (value, value_length);
}
if (bytes_left > 0) {
errno = EPROTO;
return -1;
} }
return 0; return 0;
} }
......
...@@ -107,7 +107,9 @@ namespace zmq ...@@ -107,7 +107,9 @@ namespace zmq
void send_zap_request (const uint8_t *key); void send_zap_request (const uint8_t *key);
int receive_and_process_zap_reply (); int receive_and_process_zap_reply ();
int parse_property_list (const uint8_t *ptr, size_t length);
virtual int property (const std::string name,
const void *value, size_t length);
}; };
} }
......
...@@ -71,3 +71,53 @@ size_t zmq::mechanism_t::add_property (unsigned char *ptr, const char *name, ...@@ -71,3 +71,53 @@ size_t zmq::mechanism_t::add_property (unsigned char *ptr, const char *name,
return 1 + name_len + 4 + value_len; return 1 + name_len + 4 + value_len;
} }
int zmq::mechanism_t::parse_properties (const unsigned char *ptr_,
size_t length_)
{
size_t bytes_left = length_;
while (bytes_left > 1) {
const size_t name_length = static_cast <size_t> (*ptr_);
ptr_ += 1;
bytes_left -= 1;
if (bytes_left < name_length)
break;
const std::string name = std::string ((char *) ptr_, name_length);
ptr_ += name_length;
bytes_left -= name_length;
if (bytes_left < 4)
break;
const size_t value_length = static_cast <size_t> (get_uint32 (ptr_));
ptr_ += 4;
bytes_left -= 4;
if (bytes_left < value_length)
break;
const uint8_t *value = ptr_;
ptr_ += value_length;
bytes_left -= value_length;
const int rc = property (name, value, value_length);
if (rc == -1)
return -1;
if (name == "Identity" && options.recv_identity)
set_peer_identity (value, value_length);
}
if (bytes_left > 0) {
errno = EPROTO;
return -1;
}
return 0;
}
int zmq::mechanism_t::property (const std::string name_,
const void *value_, size_t length_)
{
// Default implementation does not check
// property values and returns 0 to signal success.
return 0;
}
...@@ -69,6 +69,20 @@ namespace zmq ...@@ -69,6 +69,20 @@ namespace zmq
size_t add_property (unsigned char *ptr, const char *name, size_t add_property (unsigned char *ptr, const char *name,
const void *value, size_t value_len) const; const void *value, size_t value_len) const;
// Parse a list of properties. Returns 0 on success
// and -1 on error, in which case errno is set.
int parse_properties (const unsigned char *ptr_, size_t length);
// This is called by parse_property method whenever it
// parses a new property. The function should return 0
// on success and -1 on error, in which case it should
// set errno. Signaling error prevetns parser from
// parsing remaining data.
// Derived classes are supposed to override this
// method to handle custom processing.
virtual int property (const std::string name_,
const void *value_, size_t length_);
options_t options; options_t options;
private: private:
......
...@@ -99,54 +99,29 @@ int zmq::null_mechanism_t::process_handshake_message (msg_t *msg_) ...@@ -99,54 +99,29 @@ int zmq::null_mechanism_t::process_handshake_message (msg_t *msg_)
ptr += 8; ptr += 8;
bytes_left -= 8; bytes_left -= 8;
// Parse the property list int rc = parse_properties (ptr, bytes_left);
while (bytes_left > 1) { if (rc == 0) {
const size_t name_length = static_cast <size_t> (*ptr); int rc = msg_->close ();
ptr += 1; errno_assert (rc == 0);
bytes_left -= 1; rc = msg_->init ();
errno_assert (rc == 0);
if (bytes_left < name_length)
break;
const std::string name = std::string((const char *) ptr, name_length);
ptr += name_length;
bytes_left -= name_length;
if (bytes_left < 4)
break;
const size_t value_length = static_cast <size_t> (get_uint32 (ptr));
ptr += 4;
bytes_left -= 4;
if (bytes_left < value_length)
break;
const unsigned char * const value = ptr;
ptr += value_length;
bytes_left -= value_length;
if (name == "Socket-Type") {
// TODO: Implement socket type checking
}
else
if (name == "Identity" && options.recv_identity)
set_peer_identity (value, value_length);
} }
if (bytes_left > 0) {
errno = EPROTO;
return -1;
}
int rc = msg_->close ();
errno_assert (rc == 0);
rc = msg_->init ();
errno_assert (rc == 0);
ready_command_received = true; ready_command_received = true;
return 0; return rc;
} }
bool zmq::null_mechanism_t::is_handshake_complete () const bool zmq::null_mechanism_t::is_handshake_complete () const
{ {
return ready_command_received && ready_command_sent; return ready_command_received && ready_command_sent;
} }
int zmq::null_mechanism_t::property (const std::string name,
const void *value, size_t length)
{
if (name == "Socket-Type") {
// TODO: Implement socket type checking
}
return 0;
}
...@@ -40,6 +40,10 @@ namespace zmq ...@@ -40,6 +40,10 @@ namespace zmq
virtual int process_handshake_message (msg_t *msg_); virtual int process_handshake_message (msg_t *msg_);
virtual bool is_handshake_complete () const; virtual bool is_handshake_complete () const;
protected:
virtual int property (const std::string name,
const void *value, size_t length);
private: private:
bool ready_command_sent; bool ready_command_sent;
......
...@@ -285,7 +285,7 @@ int zmq::plain_mechanism_t::process_initiate_command (msg_t *msg_) ...@@ -285,7 +285,7 @@ int zmq::plain_mechanism_t::process_initiate_command (msg_t *msg_)
errno = EPROTO; errno = EPROTO;
return -1; return -1;
} }
return parse_property_list (ptr + 8, bytes_left - 8); return parse_properties (ptr + 8, bytes_left - 8);
} }
int zmq::plain_mechanism_t::ready_command (msg_t *msg_) const int zmq::plain_mechanism_t::ready_command (msg_t *msg_) const
...@@ -329,7 +329,7 @@ int zmq::plain_mechanism_t::process_ready_command (msg_t *msg_) ...@@ -329,7 +329,7 @@ int zmq::plain_mechanism_t::process_ready_command (msg_t *msg_)
errno = EPROTO; errno = EPROTO;
return -1; return -1;
} }
return parse_property_list (ptr + 8, bytes_left - 8); return parse_properties (ptr + 8, bytes_left - 8);
} }
void zmq::plain_mechanism_t::send_zap_request (const std::string &username, void zmq::plain_mechanism_t::send_zap_request (const std::string &username,
...@@ -451,42 +451,11 @@ error: ...@@ -451,42 +451,11 @@ error:
return rc; return rc;
} }
int zmq::plain_mechanism_t::parse_property_list (const unsigned char *ptr, int zmq::plain_mechanism_t::property (const std::string name,
size_t bytes_left) const void *value, size_t length)
{ {
while (bytes_left > 1) { if (name == "Socket-Type") {
const size_t name_length = static_cast <size_t> (*ptr); // TODO: Implement socket type checking
ptr += 1;
bytes_left -= 1;
if (bytes_left < name_length)
break;
const std::string name = std::string ((const char *) ptr, name_length);
ptr += name_length;
bytes_left -= name_length;
if (bytes_left < 4)
break;
const size_t value_length = static_cast <size_t> (get_uint32 (ptr));
ptr += 4;
bytes_left -= 4;
if (bytes_left < value_length)
break;
const unsigned char * const value = ptr;
ptr += value_length;
bytes_left -= value_length;
if (name == "Socket-Type") {
// TODO: Implement socket type checking
}
else
if (name == "Identity" && options.recv_identity)
set_peer_identity (value, value_length);
}
if (bytes_left > 0) {
errno = EPROTO;
return -1;
} }
return 0; return 0;
} }
...@@ -43,6 +43,11 @@ namespace zmq ...@@ -43,6 +43,11 @@ namespace zmq
virtual int zap_msg_available (); virtual int zap_msg_available ();
virtual bool is_handshake_complete () const; virtual bool is_handshake_complete () const;
protected:
virtual int property (const std::string name,
const void *value, size_t length);
private: private:
enum state_t { enum state_t {
...@@ -78,8 +83,6 @@ namespace zmq ...@@ -78,8 +83,6 @@ namespace zmq
void send_zap_request (const std::string &username, void send_zap_request (const std::string &username,
const std::string &password); const std::string &password);
int receive_and_process_zap_reply (); int receive_and_process_zap_reply ();
int parse_property_list (const unsigned char *ptr, size_t length);
}; };
} }
......
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