null_mechanism.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MPL-2.0 */
2 
3 #include "precompiled.hpp"
4 
5 #include <stddef.h>
6 #include <string.h>
7 #include <stdlib.h>
8 
9 #include "err.hpp"
10 #include "msg.hpp"
11 #include "session_base.hpp"
12 #include "null_mechanism.hpp"
13 
14 const char error_command_name[] = "\5ERROR";
15 const size_t error_command_name_len = sizeof (error_command_name) - 1;
16 const size_t error_reason_len_size = 1;
17 
18 const char ready_command_name[] = "\5READY";
19 const size_t ready_command_name_len = sizeof (ready_command_name) - 1;
20 
21 zmq::null_mechanism_t::null_mechanism_t (session_base_t *session_,
22  const std::string &peer_address_,
23  const options_t &options_) :
24  mechanism_base_t (session_, options_),
25  zap_client_t (session_, peer_address_, options_),
26  _ready_command_sent (false),
27  _error_command_sent (false),
28  _ready_command_received (false),
29  _error_command_received (false),
30  _zap_request_sent (false),
31  _zap_reply_received (false)
32 {
33 }
34 
35 zmq::null_mechanism_t::~null_mechanism_t ()
36 {
37 }
38 
39 int zmq::null_mechanism_t::next_handshake_command (msg_t *msg_)
40 {
41  if (_ready_command_sent || _error_command_sent) {
42  errno = EAGAIN;
43  return -1;
44  }
45 
46  if (zap_required () && !_zap_reply_received) {
47  if (_zap_request_sent) {
48  errno = EAGAIN;
49  return -1;
50  }
51  // Given this is a backward-incompatible change, it's behind a socket
52  // option disabled by default.
53  int rc = session->zap_connect ();
54  if (rc == -1 && options.zap_enforce_domain) {
55  session->get_socket ()->event_handshake_failed_no_detail (
56  session->get_endpoint (), EFAULT);
57  return -1;
58  }
59  if (rc == 0) {
60  send_zap_request ();
61  _zap_request_sent = true;
62 
63  // TODO actually, it is quite unlikely that we can read the ZAP
64  // reply already, but removing this has some strange side-effect
65  // (probably because the pipe's in_active flag is true until a read
66  // is attempted)
67  rc = receive_and_process_zap_reply ();
68  if (rc != 0)
69  return -1;
70 
71  _zap_reply_received = true;
72  }
73  }
74 
75  if (_zap_reply_received && status_code != "200") {
76  _error_command_sent = true;
77  if (status_code != "300") {
78  const size_t status_code_len = 3;
79  const int rc = msg_->init_size (
80  error_command_name_len + error_reason_len_size + status_code_len);
81  zmq_assert (rc == 0);
82  unsigned char *msg_data =
83  static_cast<unsigned char *> (msg_->data ());
84  memcpy (msg_data, error_command_name, error_command_name_len);
85  msg_data += error_command_name_len;
86  *msg_data = status_code_len;
87  msg_data += error_reason_len_size;
88  memcpy (msg_data, status_code.c_str (), status_code_len);
89  return 0;
90  }
91  errno = EAGAIN;
92  return -1;
93  }
94 
95  make_command_with_basic_properties (msg_, ready_command_name,
97 
98  _ready_command_sent = true;
99 
100  return 0;
101 }
102 
103 int zmq::null_mechanism_t::process_handshake_command (msg_t *msg_)
104 {
105  if (_ready_command_received || _error_command_received) {
106  session->get_socket ()->event_handshake_failed_protocol (
107  session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
108  errno = EPROTO;
109  return -1;
110  }
111 
112  const unsigned char *cmd_data =
113  static_cast<unsigned char *> (msg_->data ());
114  const size_t data_size = msg_->size ();
115 
116  int rc = 0;
117  if (data_size >= ready_command_name_len
118  && !memcmp (cmd_data, ready_command_name, ready_command_name_len))
119  rc = process_ready_command (cmd_data, data_size);
120  else if (data_size >= error_command_name_len
121  && !memcmp (cmd_data, error_command_name, error_command_name_len))
122  rc = process_error_command (cmd_data, data_size);
123  else {
124  session->get_socket ()->event_handshake_failed_protocol (
125  session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
126  errno = EPROTO;
127  rc = -1;
128  }
129 
130  if (rc == 0) {
131  rc = msg_->close ();
132  errno_assert (rc == 0);
133  rc = msg_->init ();
134  errno_assert (rc == 0);
135  }
136  return rc;
137 }
138 
139 int zmq::null_mechanism_t::process_ready_command (
140  const unsigned char *cmd_data_, size_t data_size_)
141 {
142  _ready_command_received = true;
143  return parse_metadata (cmd_data_ + ready_command_name_len,
144  data_size_ - ready_command_name_len);
145 }
146 
147 int zmq::null_mechanism_t::process_error_command (
148  const unsigned char *cmd_data_, size_t data_size_)
149 {
150  const size_t fixed_prefix_size =
152  if (data_size_ < fixed_prefix_size) {
153  session->get_socket ()->event_handshake_failed_protocol (
154  session->get_endpoint (),
156 
157  errno = EPROTO;
158  return -1;
159  }
160  const size_t error_reason_len =
161  static_cast<size_t> (cmd_data_[error_command_name_len]);
162  if (error_reason_len > data_size_ - fixed_prefix_size) {
163  session->get_socket ()->event_handshake_failed_protocol (
164  session->get_endpoint (),
166 
167  errno = EPROTO;
168  return -1;
169  }
170  const char *error_reason =
171  reinterpret_cast<const char *> (cmd_data_) + fixed_prefix_size;
172  handle_error_reason (error_reason, error_reason_len);
173  _error_command_received = true;
174  return 0;
175 }
176 
177 int zmq::null_mechanism_t::zap_msg_available ()
178 {
179  if (_zap_reply_received) {
180  errno = EFSM;
181  return -1;
182  }
183  const int rc = receive_and_process_zap_reply ();
184  if (rc == 0)
185  _zap_reply_received = true;
186  return rc == -1 ? -1 : 0;
187 }
188 
189 zmq::mechanism_t::status_t zmq::null_mechanism_t::status () const
190 {
191  if (_ready_command_sent && _ready_command_received)
192  return ready;
193 
194  const bool command_sent = _ready_command_sent || _error_command_sent;
195  const bool command_received =
196  _ready_command_received || _error_command_received;
197  return command_sent && command_received ? error : handshaking;
198 }
199 
200 void zmq::null_mechanism_t::send_zap_request ()
201 {
202  zap_client_t::send_zap_request ("NULL", 4, NULL, NULL, 0);
203 }
NULL
NULL
Definition: test_security_zap.cpp:405
ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND
#define ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND
Definition: zmq.h:425
EFSM
#define EFSM
Definition: zmq.h:159
options
Message * options
Definition: src/google/protobuf/descriptor.cc:3119
EAGAIN
#define EAGAIN
Definition: errno.hpp:14
ready_command_name
const char ready_command_name[]
Definition: null_mechanism.cpp:18
precompiled.hpp
zmq_assert
#define zmq_assert(x)
Definition: err.hpp:102
null_mechanism.hpp
string
GLsizei const GLchar *const * string
Definition: glcorearb.h:3083
errno
int errno
error
Definition: cJSON.c:88
ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_ERROR
#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_ERROR
Definition: zmq.h:432
EPROTO
#define EPROTO
Definition: err.hpp:26
errno_assert
#define errno_assert(x)
Definition: err.hpp:113
zmq::mechanism_t::status_t
status_t
Definition: mechanism.hpp:22
ready_command_name_len
const size_t ready_command_name_len
Definition: null_mechanism.cpp:19
error_reason_len_size
const size_t error_reason_len_size
Definition: null_mechanism.cpp:16
msg.hpp
err.hpp
error_command_name_len
const size_t error_command_name_len
Definition: null_mechanism.cpp:15
error_command_name
const char error_command_name[]
Definition: null_mechanism.cpp:14
session_base.hpp
EFAULT
#define EFAULT
Definition: errno.hpp:17
false
#define false
Definition: cJSON.c:70
options_
DebugStringOptions options_
Definition: src/google/protobuf/descriptor.cc:2410


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:57