libzmq  master
ZeroMQ C++ Core Engine (LIBZMQ)
options.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 "options.hpp"
34 #include "err.hpp"
35 #include "macros.hpp"
36 
38  sndhwm (1000),
39  rcvhwm (1000),
40  affinity (0),
41  identity_size (0),
42  rate (100),
43  recovery_ivl (10000),
44  multicast_hops (1),
45  multicast_maxtpdu (1500),
46  sndbuf (-1),
47  rcvbuf (-1),
48  tos (0),
49  type (-1),
50  linger (-1),
51  connect_timeout (0),
52  tcp_maxrt (0),
53  reconnect_ivl (100),
54  reconnect_ivl_max (0),
55  backlog (100),
56  maxmsgsize (-1),
57  rcvtimeo (-1),
58  sndtimeo (-1),
59  ipv6 (0),
60  immediate (0),
61  filter (false),
62  invert_matching(false),
63  recv_identity (false),
64  raw_socket (false),
65  raw_notify (true),
66  tcp_keepalive (-1),
67  tcp_keepalive_cnt (-1),
68  tcp_keepalive_idle (-1),
69  tcp_keepalive_intvl (-1),
70  mechanism (ZMQ_NULL),
71  as_server (0),
72  gss_plaintext (false),
73  socket_id (0),
74  conflate (false),
75  handshake_ivl (30000),
76  connected (false),
77  heartbeat_ttl (0),
78  heartbeat_interval (0),
79  heartbeat_timeout (-1),
80  use_fd (-1)
81 {
82  memset (curve_public_key, 0, CURVE_KEYSIZE);
83  memset (curve_secret_key, 0, CURVE_KEYSIZE);
84  memset (curve_server_key, 0, CURVE_KEYSIZE);
85 #if defined ZMQ_HAVE_VMCI
86  vmci_buffer_size = 0;
87  vmci_buffer_min_size = 0;
88  vmci_buffer_max_size = 0;
89  vmci_connect_timeout = -1;
90 #endif
91 }
92 
93 int zmq::options_t::setsockopt (int option_, const void *optval_,
94  size_t optvallen_)
95 {
96  bool is_int = (optvallen_ == sizeof (int));
97  int value = 0;
98  if (is_int) memcpy(&value, optval_, sizeof (int));
99 #if defined (ZMQ_ACT_MILITANT)
100  bool malformed = true; // Did caller pass a bad option value?
101 #endif
102 
103  switch (option_) {
104  case ZMQ_SNDHWM:
105  if (is_int && value >= 0) {
106  sndhwm = value;
107  return 0;
108  }
109  break;
110 
111  case ZMQ_RCVHWM:
112  if (is_int && value >= 0) {
113  rcvhwm = value;
114  return 0;
115  }
116  break;
117 
118  case ZMQ_AFFINITY:
119  if (optvallen_ == sizeof (uint64_t)) {
120  affinity = *((uint64_t*) optval_);
121  return 0;
122  }
123  break;
124 
125  case ZMQ_IDENTITY:
126  // Identity is any binary string from 1 to 255 octets
127  if (optvallen_ > 0 && optvallen_ < 256) {
128  identity_size = (unsigned char) optvallen_;
129  memcpy (identity, optval_, identity_size);
130  return 0;
131  }
132  break;
133 
134  case ZMQ_RATE:
135  if (is_int && value > 0) {
136  rate = value;
137  return 0;
138  }
139  break;
140 
141  case ZMQ_RECOVERY_IVL:
142  if (is_int && value >= 0) {
143  recovery_ivl = value;
144  return 0;
145  }
146  break;
147 
148  case ZMQ_SNDBUF:
149  if (is_int && value >= -1) {
150  sndbuf = value;
151  return 0;
152  }
153  break;
154 
155  case ZMQ_RCVBUF:
156  if (is_int && value >= -1) {
157  rcvbuf = value;
158  return 0;
159  }
160  break;
161 
162  case ZMQ_TOS:
163  if (is_int && value >= 0) {
164  tos = value;
165  return 0;
166  }
167  break;
168 
169  case ZMQ_LINGER:
170  if (is_int && value >= -1) {
171  linger = value;
172  return 0;
173  }
174  break;
175 
176  case ZMQ_CONNECT_TIMEOUT:
177  if (is_int && value >= 0) {
178  connect_timeout = value;
179  return 0;
180  }
181  break;
182 
183  case ZMQ_TCP_MAXRT:
184  if (is_int && value >= 0) {
185  tcp_maxrt = value;
186  return 0;
187  }
188  break;
189 
190  case ZMQ_RECONNECT_IVL:
191  if (is_int && value >= -1) {
192  reconnect_ivl = value;
193  return 0;
194  }
195  break;
196 
198  if (is_int && value >= 0) {
199  reconnect_ivl_max = value;
200  return 0;
201  }
202  break;
203 
204  case ZMQ_BACKLOG:
205  if (is_int && value >= 0) {
206  backlog = value;
207  return 0;
208  }
209  break;
210 
211  case ZMQ_MAXMSGSIZE:
212  if (optvallen_ == sizeof (int64_t)) {
213  maxmsgsize = *((int64_t *) optval_);
214  return 0;
215  }
216  break;
217 
218  case ZMQ_MULTICAST_HOPS:
219  if (is_int && value > 0) {
220  multicast_hops = value;
221  return 0;
222  }
223  break;
224 
226  if (is_int && value > 0) {
227  multicast_maxtpdu = value;
228  return 0;
229  }
230  break;
231 
232  case ZMQ_RCVTIMEO:
233  if (is_int && value >= -1) {
234  rcvtimeo = value;
235  return 0;
236  }
237  break;
238 
239  case ZMQ_SNDTIMEO:
240  if (is_int && value >= -1) {
241  sndtimeo = value;
242  return 0;
243  }
244  break;
245 
246  /* Deprecated in favor of ZMQ_IPV6 */
247  case ZMQ_IPV4ONLY:
248  if (is_int && (value == 0 || value == 1)) {
249  ipv6 = (value == 0);
250  return 0;
251  }
252  break;
253 
254  /* To replace the somewhat surprising IPV4ONLY */
255  case ZMQ_IPV6:
256  if (is_int && (value == 0 || value == 1)) {
257  ipv6 = (value != 0);
258  return 0;
259  }
260  break;
261 
262  case ZMQ_SOCKS_PROXY:
263  if (optval_ == NULL && optvallen_ == 0) {
264  socks_proxy_address.clear ();
265  return 0;
266  }
267  else
268  if (optval_ != NULL && optvallen_ > 0 ) {
270  std::string ((const char *) optval_, optvallen_);
271  return 0;
272  }
273  break;
274 
275  case ZMQ_TCP_KEEPALIVE:
276  if (is_int && (value == -1 || value == 0 || value == 1)) {
277  tcp_keepalive = value;
278  return 0;
279  }
280  break;
281 
283  if (is_int && (value == -1 || value >= 0)) {
284  tcp_keepalive_cnt = value;
285  return 0;
286  }
287  break;
288 
290  if (is_int && (value == -1 || value >= 0)) {
291  tcp_keepalive_idle = value;
292  return 0;
293  }
294  break;
295 
297  if (is_int && (value == -1 || value >= 0)) {
298  tcp_keepalive_intvl = value;
299  return 0;
300  }
301  break;
302 
303  case ZMQ_IMMEDIATE:
304  if (is_int && (value == 0 || value == 1)) {
305  immediate = value;
306  return 0;
307  }
308  break;
309 
311  if (optvallen_ == 0 && optval_ == NULL) {
312  tcp_accept_filters.clear ();
313  return 0;
314  }
315  else
316  if (optvallen_ > 0 && optvallen_ < 256 && optval_ != NULL && *((const char*) optval_) != 0) {
317  std::string filter_str ((const char *) optval_, optvallen_);
318  tcp_address_mask_t mask;
319  int rc = mask.resolve (filter_str.c_str (), ipv6);
320  if (rc == 0) {
321  tcp_accept_filters.push_back (mask);
322  return 0;
323  }
324  }
325  break;
326 
327 #if defined ZMQ_HAVE_SO_PEERCRED || defined ZMQ_HAVE_LOCAL_PEERCRED
328  case ZMQ_IPC_FILTER_UID:
329  if (optvallen_ == 0 && optval_ == NULL) {
330  ipc_uid_accept_filters.clear ();
331  return 0;
332  }
333  else
334  if (optvallen_ == sizeof (uid_t) && optval_ != NULL) {
335  ipc_uid_accept_filters.insert (*((uid_t *) optval_));
336  return 0;
337  }
338  break;
339 
340  case ZMQ_IPC_FILTER_GID:
341  if (optvallen_ == 0 && optval_ == NULL) {
342  ipc_gid_accept_filters.clear ();
343  return 0;
344  }
345  else
346  if (optvallen_ == sizeof (gid_t) && optval_ != NULL) {
347  ipc_gid_accept_filters.insert (*((gid_t *) optval_));
348  return 0;
349  }
350  break;
351 #endif
352 
353 #if defined ZMQ_HAVE_SO_PEERCRED
354  case ZMQ_IPC_FILTER_PID:
355  if (optvallen_ == 0 && optval_ == NULL) {
356  ipc_pid_accept_filters.clear ();
357  return 0;
358  }
359  else
360  if (optvallen_ == sizeof (pid_t) && optval_ != NULL) {
361  ipc_pid_accept_filters.insert (*((pid_t *) optval_));
362  return 0;
363  }
364  break;
365 #endif
366 
367  case ZMQ_PLAIN_SERVER:
368  if (is_int && (value == 0 || value == 1)) {
369  as_server = value;
370  mechanism = value? ZMQ_PLAIN: ZMQ_NULL;
371  return 0;
372  }
373  break;
374 
375  case ZMQ_PLAIN_USERNAME:
376  if (optvallen_ == 0 && optval_ == NULL) {
378  return 0;
379  }
380  else
381  if (optvallen_ > 0 && optvallen_ < 256 && optval_ != NULL) {
382  plain_username.assign ((const char *) optval_, optvallen_);
383  as_server = 0;
385  return 0;
386  }
387  break;
388 
389  case ZMQ_PLAIN_PASSWORD:
390  if (optvallen_ == 0 && optval_ == NULL) {
392  return 0;
393  }
394  else
395  if (optvallen_ > 0 && optvallen_ < 256 && optval_ != NULL) {
396  plain_password.assign ((const char *) optval_, optvallen_);
397  as_server = 0;
399  return 0;
400  }
401  break;
402 
403  case ZMQ_ZAP_DOMAIN:
404  if (optvallen_ < 256) {
405  zap_domain.assign ((const char *) optval_, optvallen_);
406  return 0;
407  }
408  break;
409 
410  // If curve encryption isn't built, these options provoke EINVAL
411 #ifdef ZMQ_HAVE_CURVE
412  case ZMQ_CURVE_SERVER:
413  if (is_int && (value == 0 || value == 1)) {
414  as_server = value;
415  mechanism = value? ZMQ_CURVE: ZMQ_NULL;
416  return 0;
417  }
418  break;
419 
420  case ZMQ_CURVE_PUBLICKEY:
421  // TODO: refactor repeated code for these three options
422  // into set_curve_key (destination, optval, optlen) method
423  // ==> set_curve_key (curve_public_key, optval_, optvallen_);
424  if (optvallen_ == CURVE_KEYSIZE) {
425  memcpy (curve_public_key, optval_, CURVE_KEYSIZE);
427  return 0;
428  }
429  else
430  if (optvallen_ == CURVE_KEYSIZE_Z85 + 1) {
431  if (zmq_z85_decode (curve_public_key, (char *) optval_)) {
433  return 0;
434  }
435  }
436  else
437  // Deprecated, not symmetrical with zmq_getsockopt
438  if (optvallen_ == CURVE_KEYSIZE_Z85) {
439  char z85_key [CURVE_KEYSIZE_Z85 + 1];
440  memcpy (z85_key, (char *) optval_, CURVE_KEYSIZE_Z85);
441  z85_key [CURVE_KEYSIZE_Z85] = 0;
442  if (zmq_z85_decode (curve_public_key, z85_key)) {
444  return 0;
445  }
446  }
447  break;
448 
449  case ZMQ_CURVE_SECRETKEY:
450  if (optvallen_ == CURVE_KEYSIZE) {
451  memcpy (curve_secret_key, optval_, CURVE_KEYSIZE);
453  return 0;
454  }
455  else
456  if (optvallen_ == CURVE_KEYSIZE_Z85 + 1) {
457  if (zmq_z85_decode (curve_secret_key, (char *) optval_)) {
459  return 0;
460  }
461  }
462  else
463  // Deprecated, not symmetrical with zmq_getsockopt
464  if (optvallen_ == CURVE_KEYSIZE_Z85) {
465  char z85_key [CURVE_KEYSIZE_Z85 + 1];
466  memcpy (z85_key, (char *) optval_, CURVE_KEYSIZE_Z85);
467  z85_key [CURVE_KEYSIZE_Z85] = 0;
468  if (zmq_z85_decode (curve_secret_key, z85_key)) {
470  return 0;
471  }
472  }
473  break;
474 
475  case ZMQ_CURVE_SERVERKEY:
476  if (optvallen_ == CURVE_KEYSIZE) {
477  memcpy (curve_server_key, optval_, CURVE_KEYSIZE);
479  as_server = 0;
480  return 0;
481  }
482  else
483  if (optvallen_ == CURVE_KEYSIZE_Z85 + 1) {
484  if (zmq_z85_decode (curve_server_key, (char *) optval_)) {
486  as_server = 0;
487  return 0;
488  }
489  }
490  else
491  // Deprecated, not symmetrical with zmq_getsockopt
492  if (optvallen_ == CURVE_KEYSIZE_Z85) {
493  char z85_key [CURVE_KEYSIZE_Z85 + 1];
494  memcpy (z85_key, (char *) optval_, CURVE_KEYSIZE_Z85);
495  z85_key [CURVE_KEYSIZE_Z85] = 0;
496  if (zmq_z85_decode (curve_server_key, z85_key)) {
498  as_server = 0;
499  return 0;
500  }
501  }
502  break;
503 #endif
504 
505  case ZMQ_CONFLATE:
506  if (is_int && (value == 0 || value == 1)) {
507  conflate = (value != 0);
508  return 0;
509  }
510  break;
511 
512  // If libgssapi isn't installed, these options provoke EINVAL
513 #ifdef HAVE_LIBGSSAPI_KRB5
514  case ZMQ_GSSAPI_SERVER:
515  if (is_int && (value == 0 || value == 1)) {
516  as_server = value;
518  return 0;
519  }
520  break;
521 
523  if (optvallen_ > 0 && optvallen_ < 256 && optval_ != NULL) {
524  gss_principal.assign ((const char *) optval_, optvallen_);
526  return 0;
527  }
528  break;
529 
531  if (optvallen_ > 0 && optvallen_ < 256 && optval_ != NULL) {
532  gss_service_principal.assign ((const char *) optval_, optvallen_);
534  as_server = 0;
535  return 0;
536  }
537  break;
538 
540  if (is_int && (value == 0 || value == 1)) {
541  gss_plaintext = (value != 0);
542  return 0;
543  }
544  break;
545 #endif
546 
547  case ZMQ_HANDSHAKE_IVL:
548  if (is_int && value >= 0) {
549  handshake_ivl = value;
550  return 0;
551  }
552  break;
553 
554  case ZMQ_INVERT_MATCHING:
555  if (is_int) {
556  invert_matching = (value != 0);
557  return 0;
558  }
559  break;
560 
561  case ZMQ_HEARTBEAT_IVL:
562  if (is_int && value >= 0) {
563  heartbeat_interval = value;
564  return 0;
565  }
566  break;
567 
568  case ZMQ_HEARTBEAT_TTL:
569  // Convert this to deciseconds from milliseconds
570  value = value / 100;
571  if (is_int && value >= 0 && value <= 6553) {
572  heartbeat_ttl = (uint16_t)value;
573  return 0;
574  }
575  break;
576 
578  if (is_int && value >= 0) {
579  heartbeat_timeout = value;
580  return 0;
581  }
582  break;
583 
584 #ifdef ZMQ_HAVE_VMCI
586  if (optvallen_ == sizeof (uint64_t)) {
587  vmci_buffer_size = *((uint64_t*) optval_);
588  return 0;
589  }
590  break;
591 
593  if (optvallen_ == sizeof (uint64_t)) {
594  vmci_buffer_min_size = *((uint64_t*) optval_);
595  return 0;
596  }
597  break;
598 
600  if (optvallen_ == sizeof (uint64_t)) {
601  vmci_buffer_max_size = *((uint64_t*) optval_);
602  return 0;
603  }
604  break;
605 
607  if (optvallen_ == sizeof (int)) {
608  vmci_connect_timeout = *((int*) optval_);
609  return 0;
610  }
611  break;
612 #endif
613 
614  case ZMQ_USE_FD:
615  if (is_int && value >= -1) {
616  use_fd = value;
617  return 0;
618  }
619  break;
620 
621  default:
622 #if defined (ZMQ_ACT_MILITANT)
623  // There are valid scenarios for probing with unknown socket option
624  // values, e.g. to check if security is enabled or not. This will not
625  // provoke a militant assert. However, passing bad values to a valid
626  // socket option will, if ZMQ_ACT_MILITANT is defined.
627  malformed = false;
628 #endif
629  break;
630  }
631 #if defined (ZMQ_ACT_MILITANT)
632  // There is no valid use case for passing an error back to the application
633  // when it sent malformed arguments to a socket option. Use ./configure
634  // --with-militant to enable this checking.
635  if (malformed)
636  zmq_assert (false);
637 #endif
638  errno = EINVAL;
639  return -1;
640 }
641 
642 int zmq::options_t::getsockopt (int option_, void *optval_, size_t *optvallen_) const
643 {
644  bool is_int = (*optvallen_ == sizeof (int));
645  int *value = (int *) optval_;
646 #if defined (ZMQ_ACT_MILITANT)
647  bool malformed = true; // Did caller pass a bad option value?
648 #endif
649 
650  switch (option_) {
651  case ZMQ_SNDHWM:
652  if (is_int) {
653  *value = sndhwm;
654  return 0;
655  }
656  break;
657 
658  case ZMQ_RCVHWM:
659  if (is_int) {
660  *value = rcvhwm;
661  return 0;
662  }
663  break;
664 
665  case ZMQ_AFFINITY:
666  if (*optvallen_ == sizeof (uint64_t)) {
667  *((uint64_t *) optval_) = affinity;
668  return 0;
669  }
670  break;
671 
672  case ZMQ_IDENTITY:
673  if (*optvallen_ >= identity_size) {
674  memcpy (optval_, identity, identity_size);
675  *optvallen_ = identity_size;
676  return 0;
677  }
678  break;
679 
680  case ZMQ_RATE:
681  if (is_int) {
682  *value = rate;
683  return 0;
684  }
685  break;
686 
687  case ZMQ_RECOVERY_IVL:
688  if (is_int) {
689  *value = recovery_ivl;
690  return 0;
691  }
692  break;
693 
694  case ZMQ_SNDBUF:
695  if (is_int) {
696  *value = sndbuf;
697  return 0;
698  }
699  break;
700 
701  case ZMQ_RCVBUF:
702  if (is_int) {
703  *value = rcvbuf;
704  return 0;
705  }
706  break;
707 
708  case ZMQ_TOS:
709  if (is_int) {
710  *value = tos;
711  return 0;
712  }
713  break;
714 
715  case ZMQ_TYPE:
716  if (is_int) {
717  *value = type;
718  return 0;
719  }
720  break;
721 
722  case ZMQ_LINGER:
723  if (is_int) {
724  *value = linger;
725  return 0;
726  }
727  break;
728 
729  case ZMQ_CONNECT_TIMEOUT:
730  if (is_int) {
731  *value = connect_timeout;
732  return 0;
733  }
734  break;
735 
736  case ZMQ_TCP_MAXRT:
737  if (is_int) {
738  *value = tcp_maxrt;
739  return 0;
740  }
741  break;
742 
743  case ZMQ_RECONNECT_IVL:
744  if (is_int) {
745  *value = reconnect_ivl;
746  return 0;
747  }
748  break;
749 
751  if (is_int) {
752  *value = reconnect_ivl_max;
753  return 0;
754  }
755  break;
756 
757  case ZMQ_BACKLOG:
758  if (is_int) {
759  *value = backlog;
760  return 0;
761  }
762  break;
763 
764  case ZMQ_MAXMSGSIZE:
765  if (*optvallen_ == sizeof (int64_t)) {
766  *((int64_t *) optval_) = maxmsgsize;
767  *optvallen_ = sizeof (int64_t);
768  return 0;
769  }
770  break;
771 
772  case ZMQ_MULTICAST_HOPS:
773  if (is_int) {
774  *value = multicast_hops;
775  return 0;
776  }
777  break;
778 
780  if (is_int) {
781  *value = multicast_maxtpdu;
782  return 0;
783  }
784  break;
785 
786  case ZMQ_RCVTIMEO:
787  if (is_int) {
788  *value = rcvtimeo;
789  return 0;
790  }
791  break;
792 
793  case ZMQ_SNDTIMEO:
794  if (is_int) {
795  *value = sndtimeo;
796  return 0;
797  }
798  break;
799 
800  case ZMQ_IPV4ONLY:
801  if (is_int) {
802  *value = 1 - ipv6;
803  return 0;
804  }
805  break;
806 
807  case ZMQ_IPV6:
808  if (is_int) {
809  *value = ipv6;
810  return 0;
811  }
812  break;
813 
814  case ZMQ_IMMEDIATE:
815  if (is_int) {
816  *value = immediate;
817  return 0;
818  }
819  break;
820 
821  case ZMQ_SOCKS_PROXY:
822  if (*optvallen_ >= socks_proxy_address.size () + 1) {
823  memcpy (optval_, socks_proxy_address.c_str (), socks_proxy_address.size () + 1);
824  *optvallen_ = socks_proxy_address.size () + 1;
825  return 0;
826  }
827  break;
828 
829  case ZMQ_TCP_KEEPALIVE:
830  if (is_int) {
831  *value = tcp_keepalive;
832  return 0;
833  }
834  break;
835 
837  if (is_int) {
838  *value = tcp_keepalive_cnt;
839  return 0;
840  }
841  break;
842 
844  if (is_int) {
845  *value = tcp_keepalive_idle;
846  return 0;
847  }
848  break;
849 
851  if (is_int) {
852  *value = tcp_keepalive_intvl;
853  return 0;
854  }
855  break;
856 
857  case ZMQ_MECHANISM:
858  if (is_int) {
859  *value = mechanism;
860  return 0;
861  }
862  break;
863 
864  case ZMQ_PLAIN_SERVER:
865  if (is_int) {
866  *value = as_server && mechanism == ZMQ_PLAIN;
867  return 0;
868  }
869  break;
870 
871  case ZMQ_PLAIN_USERNAME:
872  if (*optvallen_ >= plain_username.size () + 1) {
873  memcpy (optval_, plain_username.c_str (), plain_username.size () + 1);
874  *optvallen_ = plain_username.size () + 1;
875  return 0;
876  }
877  break;
878 
879  case ZMQ_PLAIN_PASSWORD:
880  if (*optvallen_ >= plain_password.size () + 1) {
881  memcpy (optval_, plain_password.c_str (), plain_password.size () + 1);
882  *optvallen_ = plain_password.size () + 1;
883  return 0;
884  }
885  break;
886 
887  case ZMQ_ZAP_DOMAIN:
888  if (*optvallen_ >= zap_domain.size () + 1) {
889  memcpy (optval_, zap_domain.c_str (), zap_domain.size () + 1);
890  *optvallen_ = zap_domain.size () + 1;
891  return 0;
892  }
893  break;
894 
895  // If curve encryption isn't built, these options provoke EINVAL
896 #ifdef ZMQ_HAVE_CURVE
897  case ZMQ_CURVE_SERVER:
898  if (is_int) {
899  *value = as_server && mechanism == ZMQ_CURVE;
900  return 0;
901  }
902  break;
903 
904  case ZMQ_CURVE_PUBLICKEY:
905  if (*optvallen_ == CURVE_KEYSIZE) {
906  memcpy (optval_, curve_public_key, CURVE_KEYSIZE);
907  return 0;
908  }
909  else
910  if (*optvallen_ == CURVE_KEYSIZE_Z85 + 1) {
911  zmq_z85_encode ((char *) optval_, curve_public_key, CURVE_KEYSIZE);
912  return 0;
913  }
914  break;
915 
916  case ZMQ_CURVE_SECRETKEY:
917  if (*optvallen_ == CURVE_KEYSIZE) {
918  memcpy (optval_, curve_secret_key, CURVE_KEYSIZE);
919  return 0;
920  }
921  else
922  if (*optvallen_ == CURVE_KEYSIZE_Z85 + 1) {
923  zmq_z85_encode ((char *) optval_, curve_secret_key, CURVE_KEYSIZE);
924  return 0;
925  }
926  break;
927 
928  case ZMQ_CURVE_SERVERKEY:
929  if (*optvallen_ == CURVE_KEYSIZE) {
930  memcpy (optval_, curve_server_key, CURVE_KEYSIZE);
931  return 0;
932  }
933  else
934  if (*optvallen_ == CURVE_KEYSIZE_Z85 + 1) {
935  zmq_z85_encode ((char *) optval_, curve_server_key, CURVE_KEYSIZE);
936  return 0;
937  }
938  break;
939 #endif
940 
941  case ZMQ_CONFLATE:
942  if (is_int) {
943  *value = conflate;
944  return 0;
945  }
946  break;
947 
948  // If libgssapi isn't installed, these options provoke EINVAL
949 #ifdef HAVE_LIBGSSAPI_KRB5
950  case ZMQ_GSSAPI_SERVER:
951  if (is_int) {
952  *value = as_server && mechanism == ZMQ_GSSAPI;
953  return 0;
954  }
955  break;
956 
958  if (*optvallen_ >= gss_principal.size () + 1) {
959  memcpy (optval_, gss_principal.c_str (), gss_principal.size () + 1);
960  *optvallen_ = gss_principal.size () + 1;
961  return 0;
962  }
963  break;
964 
966  if (*optvallen_ >= gss_service_principal.size () + 1) {
967  memcpy (optval_, gss_service_principal.c_str (), gss_service_principal.size () + 1);
968  *optvallen_ = gss_service_principal.size () + 1;
969  return 0;
970  }
971  break;
972 
974  if (is_int) {
975  *value = gss_plaintext;
976  return 0;
977  }
978  break;
979 #endif
980 
981  case ZMQ_HANDSHAKE_IVL:
982  if (is_int) {
983  *value = handshake_ivl;
984  return 0;
985  }
986  break;
987 
988  case ZMQ_INVERT_MATCHING:
989  if (is_int) {
990  *value = invert_matching;
991  return 0;
992  }
993  break;
994 
995  case ZMQ_HEARTBEAT_IVL:
996  if (is_int) {
997  *value = heartbeat_interval;
998  return 0;
999  }
1000  break;
1001 
1002  case ZMQ_HEARTBEAT_TTL:
1003  if (is_int) {
1004  // Convert the internal deciseconds value to milliseconds
1005  *value = heartbeat_ttl * 100;
1006  return 0;
1007  }
1008  break;
1009 
1010  case ZMQ_HEARTBEAT_TIMEOUT:
1011  if (is_int) {
1012  *value = heartbeat_timeout;
1013  return 0;
1014  }
1015  break;
1016 
1017  case ZMQ_USE_FD:
1018  if (is_int) {
1019  *value = use_fd;
1020  return 0;
1021  }
1022  break;
1023 
1024  default:
1025 #if defined (ZMQ_ACT_MILITANT)
1026  malformed = false;
1027 #endif
1028  break;
1029  }
1030 #if defined (ZMQ_ACT_MILITANT)
1031  if (malformed)
1032  zmq_assert (false);
1033 #endif
1034  errno = EINVAL;
1035  return -1;
1036 }
1037 
1038 bool zmq::options_t::is_valid (int option_) const
1039 {
1040  LIBZMQ_UNUSED (option_);
1041  return true;
1042 }
#define ZMQ_PLAIN_USERNAME
Definition: zmq.h:298
std::string plain_username
Definition: options.hpp:189
#define ZMQ_RECONNECT_IVL_MAX
Definition: zmq.h:279
bool invert_matching
Definition: options.hpp:143
#define ZMQ_RATE
Definition: zmq.h:268
bool gss_plaintext
Definition: options.hpp:202
#define ZMQ_CONFLATE
Definition: zmq.h:307
int heartbeat_timeout
Definition: options.hpp:225
#define ZMQ_TCP_KEEPALIVE_INTVL
Definition: zmq.h:291
#define ZMQ_RECOVERY_IVL
Definition: zmq.h:269
#define ZMQ_CURVE_SERVERKEY
Definition: zmq.h:303
#define ZMQ_SOCKS_PROXY
Definition: zmq.h:317
#define ZMQ_PLAIN
Definition: zmq.h:350
#define ZMQ_TCP_KEEPALIVE
Definition: zmq.h:288
int multicast_hops
Definition: options.hpp:83
#define CURVE_KEYSIZE_Z85
Definition: options.hpp:52
#define ZMQ_RCVHWM
Definition: zmq.h:282
std::string socks_proxy_address
Definition: options.hpp:153
#define ZMQ_CURVE_SECRETKEY
Definition: zmq.h:302
#define zmq_assert(x)
Definition: err.hpp:119
std::string gss_principal
Definition: options.hpp:198
#define ZMQ_TCP_KEEPALIVE_IDLE
Definition: zmq.h:290
int64_t maxmsgsize
Definition: options.hpp:124
#define ZMQ_HEARTBEAT_TIMEOUT
Definition: zmq.h:328
#define ZMQ_MAXMSGSIZE
Definition: zmq.h:280
#define ZMQ_BACKLOG
Definition: zmq.h:278
#define ZMQ_IPC_FILTER_GID
Definition: zmq.h:361
int getsockopt(int option_, void *optval_, size_t *optvallen_) const
Definition: options.cpp:642
#define ZMQ_CURVE
Definition: zmq.h:351
#define ZMQ_HEARTBEAT_IVL
Definition: zmq.h:326
int connect_timeout
Definition: options.hpp:105
#define ZMQ_TCP_MAXRT
Definition: zmq.h:331
#define ZMQ_SNDBUF
Definition: zmq.h:270
#define ZMQ_IPC_FILTER_UID
Definition: zmq.h:360
int resolve(const char *name_, bool ipv6_)
#define ZMQ_PLAIN_PASSWORD
Definition: zmq.h:299
#define ZMQ_CURVE_PUBLICKEY
Definition: zmq.h:301
#define ZMQ_MULTICAST_MAXTPDU
Definition: zmq.h:333
#define ZMQ_IPV6
Definition: zmq.h:295
#define ZMQ_PLAIN_SERVER
Definition: zmq.h:297
uint64_t affinity
Definition: options.hpp:70
#define ZMQ_RCVBUF
Definition: zmq.h:271
int reconnect_ivl_max
Definition: options.hpp:118
#define ZMQ_ZAP_DOMAIN
Definition: zmq.h:308
#define ZMQ_VMCI_BUFFER_SIZE
Definition: zmq.h:334
uint8_t curve_server_key[CURVE_KEYSIZE]
Definition: options.hpp:195
uint8_t curve_secret_key[CURVE_KEYSIZE]
Definition: options.hpp:194
#define ZMQ_TYPE
Definition: zmq.h:275
#define ZMQ_SNDHWM
Definition: zmq.h:281
#define ZMQ_LINGER
Definition: zmq.h:276
#define ZMQ_SNDTIMEO
Definition: zmq.h:285
#define ZMQ_GSSAPI_PLAINTEXT
Definition: zmq.h:315
#define ZMQ_IDENTITY
Definition: zmq.h:265
#define ZMQ_IPC_FILTER_PID
Definition: zmq.h:359
#define ZMQ_TCP_ACCEPT_FILTER
Definition: zmq.h:358
std::string gss_service_principal
Definition: options.hpp:199
int recovery_ivl
Definition: options.hpp:80
#define ZMQ_MULTICAST_HOPS
Definition: zmq.h:283
int tcp_keepalive_idle
Definition: options.hpp:159
#define ZMQ_IPV4ONLY
Definition: zmq.h:362
#define LIBZMQ_UNUSED(object)
Definition: macros.hpp:6
#define ZMQ_NULL
Definition: zmq.h:349
#define ZMQ_VMCI_CONNECT_TIMEOUT
Definition: zmq.h:337
unsigned char identity[256]
Definition: options.hpp:74
int multicast_maxtpdu
Definition: options.hpp:87
std::string plain_password
Definition: options.hpp:190
tcp_accept_filters_t tcp_accept_filters
Definition: options.hpp:164
#define ZMQ_HEARTBEAT_TTL
Definition: zmq.h:327
ZMQ_EXPORT uint8_t * zmq_z85_decode(uint8_t *dest, const char *string)
Definition: zmq_utils.cpp:158
#define CURVE_KEYSIZE
Definition: options.hpp:50
#define ZMQ_USE_FD
Definition: zmq.h:338
#define ZMQ_TCP_KEEPALIVE_CNT
Definition: zmq.h:289
#define ZMQ_GSSAPI
Definition: zmq.h:352
#define ZMQ_GSSAPI_SERVICE_PRINCIPAL
Definition: zmq.h:314
#define ZMQ_VMCI_BUFFER_MAX_SIZE
Definition: zmq.h:336
#define ZMQ_CURVE_SERVER
Definition: zmq.h:300
#define ZMQ_INVERT_MATCHING
Definition: zmq.h:325
#define ZMQ_TOS
Definition: zmq.h:310
enum type_t type
uint8_t curve_public_key[CURVE_KEYSIZE]
Definition: options.hpp:193
int tcp_keepalive_cnt
Definition: options.hpp:158
bool is_valid(int option_) const
Definition: options.cpp:1038
#define ZMQ_CONNECT_TIMEOUT
Definition: zmq.h:330
#define ZMQ_VMCI_BUFFER_MIN_SIZE
Definition: zmq.h:335
int setsockopt(int option_, const void *optval_, size_t optvallen_)
Definition: options.cpp:93
#define ZMQ_AFFINITY
Definition: zmq.h:264
#define ZMQ_RECONNECT_IVL
Definition: zmq.h:277
std::string zap_domain
Definition: options.hpp:186
#define ZMQ_RCVTIMEO
Definition: zmq.h:284
#define ZMQ_IMMEDIATE
Definition: zmq.h:292
uint16_t heartbeat_ttl
Definition: options.hpp:221
int heartbeat_interval
Definition: options.hpp:223
unsigned char identity_size
Definition: options.hpp:73
#define ZMQ_GSSAPI_PRINCIPAL
Definition: zmq.h:313
ZMQ_EXPORT char * zmq_z85_encode(char *dest, const uint8_t *data, size_t size)
Definition: zmq_utils.cpp:124
#define ZMQ_MECHANISM
Definition: zmq.h:296
#define ZMQ_HANDSHAKE_IVL
Definition: zmq.h:316
int tcp_keepalive_intvl
Definition: options.hpp:160
#define ZMQ_GSSAPI_SERVER
Definition: zmq.h:312