libzmq  master
ZeroMQ C++ Core Engine (LIBZMQ)
mechanism.cpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file
3 
4  This file is part of libzmq, the ZeroMQ core engine in C++.
5 
6  libzmq is free software; you can redistribute it and/or modify it under
7  the terms of the GNU Lesser General Public License (LGPL) as published
8  by the Free Software Foundation; either version 3 of the License, or
9  (at your option) any later version.
10 
11  As a special exception, the Contributors give you permission to link
12  this library with independent modules to produce an executable,
13  regardless of the license terms of these independent modules, and to
14  copy and distribute the resulting executable under terms of your choice,
15  provided that you also meet, for each linked independent module, the
16  terms and conditions of the license of that module. An independent
17  module is a module which is not derived from or based on this library.
18  If you modify this library, you must extend this exception to your
19  version of the library.
20 
21  libzmq is distributed in the hope that it will be useful, but WITHOUT
22  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
24  License for more details.
25 
26  You should have received a copy of the GNU Lesser General Public License
27  along with this program. If not, see <http://www.gnu.org/licenses/>.
28 */
29 
30 #include "precompiled.hpp"
31 #include <string.h>
32 
33 #include "mechanism.hpp"
34 #include "options.hpp"
35 #include "msg.hpp"
36 #include "err.hpp"
37 #include "wire.hpp"
38 
40  options (options_)
41 {
42 }
43 
45 {
46 }
47 
48 void zmq::mechanism_t::set_peer_identity (const void *id_ptr, size_t id_size)
49 {
50  identity = blob_t (static_cast <const unsigned char*> (id_ptr), id_size);
51 }
52 
54 {
55  const int rc = msg_->init_size (identity.size ());
56  errno_assert (rc == 0);
57  memcpy (msg_->data (), identity.data (), identity.size ());
58  msg_->set_flags (msg_t::identity);
59 }
60 
61 void zmq::mechanism_t::set_user_id (const void *data_, size_t size_)
62 {
63  user_id = blob_t (static_cast <const unsigned char*> (data_), size_);
64  zap_properties.insert (
65  metadata_t::dict_t::value_type (
66  "User-Id", std::string ((char *) data_, size_)));
67 }
68 
70 {
71  return user_id;
72 }
73 
74 const char *zmq::mechanism_t::socket_type_string (int socket_type) const
75 {
76  static const char *names [] = {"PAIR", "PUB", "SUB", "REQ", "REP",
77  "DEALER", "ROUTER", "PULL", "PUSH",
78  "XPUB", "XSUB", "STREAM",
79  "SERVER", "CLIENT",
80  "RADIO", "DISH",
81  "GATHER", "SCATTER"};
82  zmq_assert (socket_type >= 0 && socket_type <= 17);
83  return names [socket_type];
84 }
85 
86 size_t zmq::mechanism_t::add_property (unsigned char *ptr, const char *name,
87  const void *value, size_t value_len) const
88 {
89  const size_t name_len = strlen (name);
90  zmq_assert (name_len <= 255);
91  *ptr++ = static_cast <unsigned char> (name_len);
92  memcpy (ptr, name, name_len);
93  ptr += name_len;
94  zmq_assert (value_len <= 0x7FFFFFFF);
95  put_uint32 (ptr, static_cast <uint32_t> (value_len));
96  ptr += 4;
97  memcpy (ptr, value, value_len);
98 
99  return 1 + name_len + 4 + value_len;
100 }
101 
102 int zmq::mechanism_t::parse_metadata (const unsigned char *ptr_,
103  size_t length_, bool zap_flag)
104 {
105  size_t bytes_left = length_;
106 
107  while (bytes_left > 1) {
108  const size_t name_length = static_cast <size_t> (*ptr_);
109  ptr_ += 1;
110  bytes_left -= 1;
111  if (bytes_left < name_length)
112  break;
113 
114  const std::string name = std::string ((char *) ptr_, name_length);
115  ptr_ += name_length;
116  bytes_left -= name_length;
117  if (bytes_left < 4)
118  break;
119 
120  const size_t value_length = static_cast <size_t> (get_uint32 (ptr_));
121  ptr_ += 4;
122  bytes_left -= 4;
123  if (bytes_left < value_length)
124  break;
125 
126  const uint8_t *value = ptr_;
127  ptr_ += value_length;
128  bytes_left -= value_length;
129 
130  if (name == "Identity" && options.recv_identity)
131  set_peer_identity (value, value_length);
132  else
133  if (name == "Socket-Type") {
134  const std::string socket_type ((char *) value, value_length);
135  if (!check_socket_type (socket_type)) {
136  errno = EINVAL;
137  return -1;
138  }
139  }
140  else {
141  const int rc = property (name, value, value_length);
142  if (rc == -1)
143  return -1;
144  }
145  if (zap_flag)
146  zap_properties.insert (
147  metadata_t::dict_t::value_type (
148  name, std::string ((char *) value, value_length)));
149  else
150  zmtp_properties.insert (
151  metadata_t::dict_t::value_type (
152  name, std::string ((char *) value, value_length)));
153  }
154  if (bytes_left > 0) {
155  errno = EPROTO;
156  return -1;
157  }
158  return 0;
159 }
160 
161 int zmq::mechanism_t::property (const std::string& /* name_ */,
162  const void * /* value_ */, size_t /* length_ */)
163 {
164  // Default implementation does not check
165  // property values and returns 0 to signal success.
166  return 0;
167 }
168 
169 bool zmq::mechanism_t::check_socket_type (const std::string& type_) const
170 {
171  switch (options.type) {
172  case ZMQ_REQ:
173  return type_ == "REP" || type_ == "ROUTER";
174  case ZMQ_REP:
175  return type_ == "REQ" || type_ == "DEALER";
176  case ZMQ_DEALER:
177  return type_ == "REP" || type_ == "DEALER" || type_ == "ROUTER";
178  case ZMQ_ROUTER:
179  return type_ == "REQ" || type_ == "DEALER" || type_ == "ROUTER";
180  case ZMQ_PUSH:
181  return type_ == "PULL";
182  case ZMQ_PULL:
183  return type_ == "PUSH";
184  case ZMQ_PUB:
185  return type_ == "SUB" || type_ == "XSUB";
186  case ZMQ_SUB:
187  return type_ == "PUB" || type_ == "XPUB";
188  case ZMQ_XPUB:
189  return type_ == "SUB" || type_ == "XSUB";
190  case ZMQ_XSUB:
191  return type_ == "PUB" || type_ == "XPUB";
192  case ZMQ_PAIR:
193  return type_ == "PAIR";
194  case ZMQ_SERVER:
195  return type_ == "CLIENT";
196  case ZMQ_CLIENT:
197  return type_ == "SERVER";
198  case ZMQ_RADIO:
199  return type_ == "DISH";
200  case ZMQ_DISH:
201  return type_ == "RADIO";
202  case ZMQ_GATHER:
203  return type_ == "SCATTER";
204  case ZMQ_SCATTER:
205  return type_ == "GATHER";
206  default:
207  break;
208  }
209  return false;
210 }
void set_peer_identity(const void *id_ptr, size_t id_size)
Definition: mechanism.cpp:48
mechanism_t(const options_t &options_)
Definition: mechanism.cpp:39
#define ZMQ_DISH
virtual ~mechanism_t()
Definition: mechanism.cpp:44
#define ZMQ_DEALER
Definition: zmq.h:251
#define ZMQ_RADIO
#define zmq_assert(x)
Definition: err.hpp:119
#define ZMQ_SUB
Definition: zmq.h:248
#define ZMQ_XPUB
Definition: zmq.h:255
bool recv_identity
Definition: options.hpp:146
#define ZMQ_REP
Definition: zmq.h:250
#define ZMQ_XSUB
Definition: zmq.h:256
#define ZMQ_SCATTER
#define ZMQ_PUB
Definition: zmq.h:247
#define ZMQ_ROUTER
Definition: zmq.h:252
void put_uint32(unsigned char *buffer_, uint32_t value)
Definition: wire.hpp:64
#define ZMQ_PUSH
Definition: zmq.h:254
uint32_t get_uint32(const unsigned char *buffer_)
Definition: wire.hpp:72
bool check_socket_type(const std::string &type_) const
Definition: mechanism.cpp:169
int init_size(size_t size_)
Definition: msg.cpp:93
metadata_t::dict_t zmtp_properties
Definition: mechanism.hpp:119
options_t options
Definition: mechanism.hpp:124
#define ZMQ_REQ
Definition: zmq.h:249
metadata_t::dict_t zap_properties
Definition: mechanism.hpp:122
int parse_metadata(const unsigned char *ptr_, size_t length, bool zap_flag=false)
Definition: mechanism.cpp:102
std::basic_string< unsigned char > blob_t
Definition: blob.hpp:134
#define EPROTO
Definition: err.hpp:58
#define ZMQ_GATHER
void peer_identity(msg_t *msg_)
Definition: mechanism.cpp:53
const char * socket_type_string(int socket_type) const
Definition: mechanism.cpp:74
#define ZMQ_SERVER
void set_flags(unsigned char flags_)
Definition: msg.cpp:384
#define errno_assert(x)
Definition: err.hpp:129
virtual int property(const std::string &name_, const void *value_, size_t length_)
Definition: mechanism.cpp:161
#define ZMQ_PAIR
Definition: zmq.h:246
unsigned char data[max_vsm_size]
Definition: msg.hpp:187
size_t add_property(unsigned char *ptr, const char *name, const void *value, size_t value_len) const
Definition: mechanism.cpp:86
void set_user_id(const void *user_id, size_t size)
Definition: mechanism.cpp:61
blob_t get_user_id() const
Definition: mechanism.cpp:69
#define ZMQ_PULL
Definition: zmq.h:253
#define ZMQ_CLIENT