Line data Source code
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 :
37 11474 : zmq::options_t::options_t () :
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 126214 : use_fd (-1)
81 : {
82 11474 : memset (curve_public_key, 0, CURVE_KEYSIZE);
83 11474 : 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 11474 : }
92 :
93 2397 : int zmq::options_t::setsockopt (int option_, const void *optval_,
94 : size_t optvallen_)
95 : {
96 2397 : bool is_int = (optvallen_ == sizeof (int));
97 2397 : int value = 0;
98 2397 : 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 2397 : switch (option_) {
104 : case ZMQ_SNDHWM:
105 60 : if (is_int && value >= 0) {
106 60 : sndhwm = value;
107 60 : return 0;
108 : }
109 : break;
110 :
111 : case ZMQ_RCVHWM:
112 42 : if (is_int && value >= 0) {
113 42 : rcvhwm = value;
114 42 : return 0;
115 : }
116 : break;
117 :
118 : case ZMQ_AFFINITY:
119 0 : if (optvallen_ == sizeof (uint64_t)) {
120 0 : affinity = *((uint64_t*) optval_);
121 0 : return 0;
122 : }
123 : break;
124 :
125 : case ZMQ_IDENTITY:
126 : // Identity is any binary string from 1 to 255 octets
127 366 : if (optvallen_ > 0 && optvallen_ < 256) {
128 366 : identity_size = (unsigned char) optvallen_;
129 366 : memcpy (identity, optval_, identity_size);
130 366 : return 0;
131 : }
132 : break;
133 :
134 : case ZMQ_RATE:
135 0 : if (is_int && value > 0) {
136 0 : rate = value;
137 0 : return 0;
138 : }
139 : break;
140 :
141 : case ZMQ_RECOVERY_IVL:
142 0 : if (is_int && value >= 0) {
143 0 : recovery_ivl = value;
144 0 : return 0;
145 : }
146 : break;
147 :
148 : case ZMQ_SNDBUF:
149 3 : if (is_int && value >= -1) {
150 3 : sndbuf = value;
151 3 : return 0;
152 : }
153 : break;
154 :
155 : case ZMQ_RCVBUF:
156 3 : if (is_int && value >= -1) {
157 3 : rcvbuf = value;
158 3 : return 0;
159 : }
160 : break;
161 :
162 : case ZMQ_TOS:
163 6 : if (is_int && value >= 0) {
164 6 : tos = value;
165 6 : return 0;
166 : }
167 : break;
168 :
169 : case ZMQ_LINGER:
170 888 : if (is_int && value >= -1) {
171 888 : linger = value;
172 888 : return 0;
173 : }
174 : break;
175 :
176 : case ZMQ_CONNECT_TIMEOUT:
177 0 : if (is_int && value >= 0) {
178 0 : connect_timeout = value;
179 0 : return 0;
180 : }
181 : break;
182 :
183 : case ZMQ_TCP_MAXRT:
184 0 : if (is_int && value >= 0) {
185 0 : tcp_maxrt = value;
186 0 : return 0;
187 : }
188 : break;
189 :
190 : case ZMQ_RECONNECT_IVL:
191 24 : if (is_int && value >= -1) {
192 24 : reconnect_ivl = value;
193 24 : return 0;
194 : }
195 : break;
196 :
197 : case ZMQ_RECONNECT_IVL_MAX:
198 0 : if (is_int && value >= 0) {
199 0 : reconnect_ivl_max = value;
200 0 : return 0;
201 : }
202 : break;
203 :
204 : case ZMQ_BACKLOG:
205 0 : if (is_int && value >= 0) {
206 0 : backlog = value;
207 0 : return 0;
208 : }
209 : break;
210 :
211 : case ZMQ_MAXMSGSIZE:
212 0 : if (optvallen_ == sizeof (int64_t)) {
213 0 : maxmsgsize = *((int64_t *) optval_);
214 0 : return 0;
215 : }
216 : break;
217 :
218 : case ZMQ_MULTICAST_HOPS:
219 0 : if (is_int && value > 0) {
220 0 : multicast_hops = value;
221 0 : return 0;
222 : }
223 : break;
224 :
225 : case ZMQ_MULTICAST_MAXTPDU:
226 0 : if (is_int && value > 0) {
227 0 : multicast_maxtpdu = value;
228 0 : return 0;
229 : }
230 : break;
231 :
232 : case ZMQ_RCVTIMEO:
233 645 : if (is_int && value >= -1) {
234 645 : rcvtimeo = value;
235 645 : return 0;
236 : }
237 : break;
238 :
239 : case ZMQ_SNDTIMEO:
240 135 : if (is_int && value >= -1) {
241 135 : sndtimeo = value;
242 135 : return 0;
243 : }
244 : break;
245 :
246 : /* Deprecated in favor of ZMQ_IPV6 */
247 : case ZMQ_IPV4ONLY:
248 0 : if (is_int && (value == 0 || value == 1)) {
249 0 : ipv6 = (value == 0);
250 0 : return 0;
251 : }
252 : break;
253 :
254 : /* To replace the somewhat surprising IPV4ONLY */
255 : case ZMQ_IPV6:
256 30 : if (is_int && (value == 0 || value == 1)) {
257 30 : ipv6 = (value != 0);
258 30 : return 0;
259 : }
260 : break;
261 :
262 : case ZMQ_SOCKS_PROXY:
263 0 : if (optval_ == NULL && optvallen_ == 0) {
264 0 : socks_proxy_address.clear ();
265 0 : return 0;
266 : }
267 : else
268 0 : if (optval_ != NULL && optvallen_ > 0 ) {
269 0 : socks_proxy_address =
270 : std::string ((const char *) optval_, optvallen_);
271 0 : return 0;
272 : }
273 : break;
274 :
275 : case ZMQ_TCP_KEEPALIVE:
276 0 : if (is_int && (value == -1 || value == 0 || value == 1)) {
277 0 : tcp_keepalive = value;
278 0 : return 0;
279 : }
280 : break;
281 :
282 : case ZMQ_TCP_KEEPALIVE_CNT:
283 0 : if (is_int && (value == -1 || value >= 0)) {
284 0 : tcp_keepalive_cnt = value;
285 0 : return 0;
286 : }
287 : break;
288 :
289 : case ZMQ_TCP_KEEPALIVE_IDLE:
290 0 : if (is_int && (value == -1 || value >= 0)) {
291 0 : tcp_keepalive_idle = value;
292 0 : return 0;
293 : }
294 : break;
295 :
296 : case ZMQ_TCP_KEEPALIVE_INTVL:
297 0 : if (is_int && (value == -1 || value >= 0)) {
298 0 : tcp_keepalive_intvl = value;
299 0 : return 0;
300 : }
301 : break;
302 :
303 : case ZMQ_IMMEDIATE:
304 6 : if (is_int && (value == 0 || value == 1)) {
305 6 : immediate = value;
306 6 : return 0;
307 : }
308 : break;
309 :
310 : case ZMQ_TCP_ACCEPT_FILTER:
311 0 : if (optvallen_ == 0 && optval_ == NULL) {
312 0 : tcp_accept_filters.clear ();
313 0 : return 0;
314 : }
315 : else
316 0 : if (optvallen_ > 0 && optvallen_ < 256 && optval_ != NULL && *((const char*) optval_) != 0) {
317 0 : std::string filter_str ((const char *) optval_, optvallen_);
318 0 : tcp_address_mask_t mask;
319 0 : int rc = mask.resolve (filter_str.c_str (), ipv6);
320 0 : if (rc == 0) {
321 0 : tcp_accept_filters.push_back (mask);
322 0 : 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 6 : if (optvallen_ == 0 && optval_ == NULL) {
330 0 : ipc_uid_accept_filters.clear ();
331 0 : return 0;
332 : }
333 : else
334 6 : if (optvallen_ == sizeof (uid_t) && optval_ != NULL) {
335 6 : ipc_uid_accept_filters.insert (*((uid_t *) optval_));
336 6 : return 0;
337 : }
338 : break;
339 :
340 : case ZMQ_IPC_FILTER_GID:
341 9 : if (optvallen_ == 0 && optval_ == NULL) {
342 0 : ipc_gid_accept_filters.clear ();
343 0 : return 0;
344 : }
345 : else
346 9 : if (optvallen_ == sizeof (gid_t) && optval_ != NULL) {
347 9 : ipc_gid_accept_filters.insert (*((gid_t *) optval_));
348 9 : return 0;
349 : }
350 : break;
351 : #endif
352 :
353 : #if defined ZMQ_HAVE_SO_PEERCRED
354 : case ZMQ_IPC_FILTER_PID:
355 6 : if (optvallen_ == 0 && optval_ == NULL) {
356 0 : ipc_pid_accept_filters.clear ();
357 0 : return 0;
358 : }
359 : else
360 6 : if (optvallen_ == sizeof (pid_t) && optval_ != NULL) {
361 6 : ipc_pid_accept_filters.insert (*((pid_t *) optval_));
362 6 : return 0;
363 : }
364 : break;
365 : #endif
366 :
367 : case ZMQ_PLAIN_SERVER:
368 6 : if (is_int && (value == 0 || value == 1)) {
369 6 : as_server = value;
370 6 : mechanism = value? ZMQ_PLAIN: ZMQ_NULL;
371 6 : return 0;
372 : }
373 : break;
374 :
375 : case ZMQ_PLAIN_USERNAME:
376 9 : if (optvallen_ == 0 && optval_ == NULL) {
377 0 : mechanism = ZMQ_NULL;
378 0 : return 0;
379 : }
380 : else
381 9 : if (optvallen_ > 0 && optvallen_ < 256 && optval_ != NULL) {
382 9 : plain_username.assign ((const char *) optval_, optvallen_);
383 9 : as_server = 0;
384 9 : mechanism = ZMQ_PLAIN;
385 9 : return 0;
386 : }
387 : break;
388 :
389 : case ZMQ_PLAIN_PASSWORD:
390 9 : if (optvallen_ == 0 && optval_ == NULL) {
391 0 : mechanism = ZMQ_NULL;
392 0 : return 0;
393 : }
394 : else
395 9 : if (optvallen_ > 0 && optvallen_ < 256 && optval_ != NULL) {
396 9 : plain_password.assign ((const char *) optval_, optvallen_);
397 9 : as_server = 0;
398 9 : mechanism = ZMQ_PLAIN;
399 9 : return 0;
400 : }
401 : break;
402 :
403 : case ZMQ_ZAP_DOMAIN:
404 12 : if (optvallen_ < 256) {
405 12 : 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 6 : if (is_int && (value == 0 || value == 1)) {
414 6 : as_server = value;
415 6 : mechanism = value? ZMQ_CURVE: ZMQ_NULL;
416 6 : 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 24 : if (optvallen_ == CURVE_KEYSIZE) {
425 0 : memcpy (curve_public_key, optval_, CURVE_KEYSIZE);
426 0 : mechanism = ZMQ_CURVE;
427 0 : return 0;
428 : }
429 : else
430 24 : if (optvallen_ == CURVE_KEYSIZE_Z85 + 1) {
431 15 : if (zmq_z85_decode (curve_public_key, (char *) optval_)) {
432 15 : mechanism = ZMQ_CURVE;
433 15 : return 0;
434 : }
435 : }
436 : else
437 : // Deprecated, not symmetrical with zmq_getsockopt
438 9 : if (optvallen_ == CURVE_KEYSIZE_Z85) {
439 : char z85_key [CURVE_KEYSIZE_Z85 + 1];
440 : memcpy (z85_key, (char *) optval_, CURVE_KEYSIZE_Z85);
441 6 : z85_key [CURVE_KEYSIZE_Z85] = 0;
442 6 : if (zmq_z85_decode (curve_public_key, z85_key)) {
443 6 : mechanism = ZMQ_CURVE;
444 6 : return 0;
445 : }
446 : }
447 : break;
448 :
449 : case ZMQ_CURVE_SECRETKEY:
450 27 : if (optvallen_ == CURVE_KEYSIZE) {
451 0 : memcpy (curve_secret_key, optval_, CURVE_KEYSIZE);
452 0 : mechanism = ZMQ_CURVE;
453 0 : return 0;
454 : }
455 : else
456 27 : if (optvallen_ == CURVE_KEYSIZE_Z85 + 1) {
457 18 : if (zmq_z85_decode (curve_secret_key, (char *) optval_)) {
458 18 : mechanism = ZMQ_CURVE;
459 18 : return 0;
460 : }
461 : }
462 : else
463 : // Deprecated, not symmetrical with zmq_getsockopt
464 9 : if (optvallen_ == CURVE_KEYSIZE_Z85) {
465 : char z85_key [CURVE_KEYSIZE_Z85 + 1];
466 : memcpy (z85_key, (char *) optval_, CURVE_KEYSIZE_Z85);
467 6 : z85_key [CURVE_KEYSIZE_Z85] = 0;
468 6 : if (zmq_z85_decode (curve_secret_key, z85_key)) {
469 6 : mechanism = ZMQ_CURVE;
470 6 : return 0;
471 : }
472 : }
473 : break;
474 :
475 : case ZMQ_CURVE_SERVERKEY:
476 21 : if (optvallen_ == CURVE_KEYSIZE) {
477 0 : memcpy (curve_server_key, optval_, CURVE_KEYSIZE);
478 0 : mechanism = ZMQ_CURVE;
479 0 : as_server = 0;
480 0 : return 0;
481 : }
482 : else
483 21 : if (optvallen_ == CURVE_KEYSIZE_Z85 + 1) {
484 15 : if (zmq_z85_decode (curve_server_key, (char *) optval_)) {
485 15 : mechanism = ZMQ_CURVE;
486 15 : as_server = 0;
487 15 : return 0;
488 : }
489 : }
490 : else
491 : // Deprecated, not symmetrical with zmq_getsockopt
492 6 : if (optvallen_ == CURVE_KEYSIZE_Z85) {
493 : char z85_key [CURVE_KEYSIZE_Z85 + 1];
494 : memcpy (z85_key, (char *) optval_, CURVE_KEYSIZE_Z85);
495 3 : z85_key [CURVE_KEYSIZE_Z85] = 0;
496 3 : if (zmq_z85_decode (curve_server_key, z85_key)) {
497 3 : mechanism = ZMQ_CURVE;
498 3 : as_server = 0;
499 3 : return 0;
500 : }
501 : }
502 : break;
503 : #endif
504 :
505 : case ZMQ_CONFLATE:
506 3 : if (is_int && (value == 0 || value == 1)) {
507 3 : conflate = (value != 0);
508 3 : 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;
517 : mechanism = ZMQ_GSSAPI;
518 : return 0;
519 : }
520 : break;
521 :
522 : case ZMQ_GSSAPI_PRINCIPAL:
523 : if (optvallen_ > 0 && optvallen_ < 256 && optval_ != NULL) {
524 : gss_principal.assign ((const char *) optval_, optvallen_);
525 : mechanism = ZMQ_GSSAPI;
526 : return 0;
527 : }
528 : break;
529 :
530 : case ZMQ_GSSAPI_SERVICE_PRINCIPAL:
531 : if (optvallen_ > 0 && optvallen_ < 256 && optval_ != NULL) {
532 : gss_service_principal.assign ((const char *) optval_, optvallen_);
533 : mechanism = ZMQ_GSSAPI;
534 : as_server = 0;
535 : return 0;
536 : }
537 : break;
538 :
539 : case ZMQ_GSSAPI_PLAINTEXT:
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 6 : if (is_int && value >= 0) {
549 6 : handshake_ivl = value;
550 6 : return 0;
551 : }
552 : break;
553 :
554 : case ZMQ_INVERT_MATCHING:
555 9 : if (is_int) {
556 9 : invert_matching = (value != 0);
557 9 : return 0;
558 : }
559 : break;
560 :
561 : case ZMQ_HEARTBEAT_IVL:
562 12 : if (is_int && value >= 0) {
563 12 : heartbeat_interval = value;
564 12 : return 0;
565 : }
566 : break;
567 :
568 : case ZMQ_HEARTBEAT_TTL:
569 : // Convert this to deciseconds from milliseconds
570 3 : value = value / 100;
571 3 : if (is_int && value >= 0 && value <= 6553) {
572 3 : heartbeat_ttl = (uint16_t)value;
573 3 : return 0;
574 : }
575 : break;
576 :
577 : case ZMQ_HEARTBEAT_TIMEOUT:
578 0 : if (is_int && value >= 0) {
579 0 : heartbeat_timeout = value;
580 0 : return 0;
581 : }
582 : break;
583 :
584 : #ifdef ZMQ_HAVE_VMCI
585 : case ZMQ_VMCI_BUFFER_SIZE:
586 : if (optvallen_ == sizeof (uint64_t)) {
587 : vmci_buffer_size = *((uint64_t*) optval_);
588 : return 0;
589 : }
590 : break;
591 :
592 : case ZMQ_VMCI_BUFFER_MIN_SIZE:
593 : if (optvallen_ == sizeof (uint64_t)) {
594 : vmci_buffer_min_size = *((uint64_t*) optval_);
595 : return 0;
596 : }
597 : break;
598 :
599 : case ZMQ_VMCI_BUFFER_MAX_SIZE:
600 : if (optvallen_ == sizeof (uint64_t)) {
601 : vmci_buffer_max_size = *((uint64_t*) optval_);
602 : return 0;
603 : }
604 : break;
605 :
606 : case ZMQ_VMCI_CONNECT_TIMEOUT:
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 21 : if (is_int && value >= -1) {
616 21 : use_fd = value;
617 21 : 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 9 : errno = EINVAL;
639 9 : return -1;
640 : }
641 :
642 60 : int zmq::options_t::getsockopt (int option_, void *optval_, size_t *optvallen_) const
643 : {
644 60 : bool is_int = (*optvallen_ == sizeof (int));
645 60 : 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 60 : switch (option_) {
651 : case ZMQ_SNDHWM:
652 9 : if (is_int) {
653 9 : *value = sndhwm;
654 9 : return 0;
655 : }
656 : break;
657 :
658 : case ZMQ_RCVHWM:
659 0 : if (is_int) {
660 0 : *value = rcvhwm;
661 0 : return 0;
662 : }
663 : break;
664 :
665 : case ZMQ_AFFINITY:
666 0 : if (*optvallen_ == sizeof (uint64_t)) {
667 0 : *((uint64_t *) optval_) = affinity;
668 0 : return 0;
669 : }
670 : break;
671 :
672 : case ZMQ_IDENTITY:
673 6 : if (*optvallen_ >= identity_size) {
674 6 : memcpy (optval_, identity, identity_size);
675 6 : *optvallen_ = identity_size;
676 6 : return 0;
677 : }
678 : break;
679 :
680 : case ZMQ_RATE:
681 0 : if (is_int) {
682 0 : *value = rate;
683 0 : return 0;
684 : }
685 : break;
686 :
687 : case ZMQ_RECOVERY_IVL:
688 0 : if (is_int) {
689 0 : *value = recovery_ivl;
690 0 : return 0;
691 : }
692 : break;
693 :
694 : case ZMQ_SNDBUF:
695 6 : if (is_int) {
696 6 : *value = sndbuf;
697 6 : return 0;
698 : }
699 : break;
700 :
701 : case ZMQ_RCVBUF:
702 6 : if (is_int) {
703 6 : *value = rcvbuf;
704 6 : return 0;
705 : }
706 : break;
707 :
708 : case ZMQ_TOS:
709 6 : if (is_int) {
710 6 : *value = tos;
711 6 : return 0;
712 : }
713 : break;
714 :
715 : case ZMQ_TYPE:
716 0 : if (is_int) {
717 0 : *value = type;
718 0 : return 0;
719 : }
720 : break;
721 :
722 : case ZMQ_LINGER:
723 6 : if (is_int) {
724 6 : *value = linger;
725 6 : return 0;
726 : }
727 : break;
728 :
729 : case ZMQ_CONNECT_TIMEOUT:
730 0 : if (is_int) {
731 0 : *value = connect_timeout;
732 0 : return 0;
733 : }
734 : break;
735 :
736 : case ZMQ_TCP_MAXRT:
737 0 : if (is_int) {
738 0 : *value = tcp_maxrt;
739 0 : return 0;
740 : }
741 : break;
742 :
743 : case ZMQ_RECONNECT_IVL:
744 0 : if (is_int) {
745 0 : *value = reconnect_ivl;
746 0 : return 0;
747 : }
748 : break;
749 :
750 : case ZMQ_RECONNECT_IVL_MAX:
751 0 : if (is_int) {
752 0 : *value = reconnect_ivl_max;
753 0 : return 0;
754 : }
755 : break;
756 :
757 : case ZMQ_BACKLOG:
758 0 : if (is_int) {
759 0 : *value = backlog;
760 0 : return 0;
761 : }
762 : break;
763 :
764 : case ZMQ_MAXMSGSIZE:
765 0 : if (*optvallen_ == sizeof (int64_t)) {
766 0 : *((int64_t *) optval_) = maxmsgsize;
767 0 : *optvallen_ = sizeof (int64_t);
768 0 : return 0;
769 : }
770 : break;
771 :
772 : case ZMQ_MULTICAST_HOPS:
773 0 : if (is_int) {
774 0 : *value = multicast_hops;
775 0 : return 0;
776 : }
777 : break;
778 :
779 : case ZMQ_MULTICAST_MAXTPDU:
780 0 : if (is_int) {
781 0 : *value = multicast_maxtpdu;
782 0 : return 0;
783 : }
784 : break;
785 :
786 : case ZMQ_RCVTIMEO:
787 0 : if (is_int) {
788 0 : *value = rcvtimeo;
789 0 : return 0;
790 : }
791 : break;
792 :
793 : case ZMQ_SNDTIMEO:
794 0 : if (is_int) {
795 0 : *value = sndtimeo;
796 0 : return 0;
797 : }
798 : break;
799 :
800 : case ZMQ_IPV4ONLY:
801 0 : if (is_int) {
802 0 : *value = 1 - ipv6;
803 0 : return 0;
804 : }
805 : break;
806 :
807 : case ZMQ_IPV6:
808 3 : if (is_int) {
809 3 : *value = ipv6;
810 3 : return 0;
811 : }
812 : break;
813 :
814 : case ZMQ_IMMEDIATE:
815 0 : if (is_int) {
816 0 : *value = immediate;
817 0 : return 0;
818 : }
819 : break;
820 :
821 : case ZMQ_SOCKS_PROXY:
822 0 : if (*optvallen_ >= socks_proxy_address.size () + 1) {
823 0 : memcpy (optval_, socks_proxy_address.c_str (), socks_proxy_address.size () + 1);
824 0 : *optvallen_ = socks_proxy_address.size () + 1;
825 0 : return 0;
826 : }
827 : break;
828 :
829 : case ZMQ_TCP_KEEPALIVE:
830 0 : if (is_int) {
831 0 : *value = tcp_keepalive;
832 0 : return 0;
833 : }
834 : break;
835 :
836 : case ZMQ_TCP_KEEPALIVE_CNT:
837 0 : if (is_int) {
838 0 : *value = tcp_keepalive_cnt;
839 0 : return 0;
840 : }
841 : break;
842 :
843 : case ZMQ_TCP_KEEPALIVE_IDLE:
844 0 : if (is_int) {
845 0 : *value = tcp_keepalive_idle;
846 0 : return 0;
847 : }
848 : break;
849 :
850 : case ZMQ_TCP_KEEPALIVE_INTVL:
851 0 : if (is_int) {
852 0 : *value = tcp_keepalive_intvl;
853 0 : return 0;
854 : }
855 : break;
856 :
857 : case ZMQ_MECHANISM:
858 0 : if (is_int) {
859 0 : *value = mechanism;
860 0 : return 0;
861 : }
862 : break;
863 :
864 : case ZMQ_PLAIN_SERVER:
865 0 : if (is_int) {
866 0 : *value = as_server && mechanism == ZMQ_PLAIN;
867 0 : return 0;
868 : }
869 : break;
870 :
871 : case ZMQ_PLAIN_USERNAME:
872 0 : if (*optvallen_ >= plain_username.size () + 1) {
873 0 : memcpy (optval_, plain_username.c_str (), plain_username.size () + 1);
874 0 : *optvallen_ = plain_username.size () + 1;
875 0 : return 0;
876 : }
877 : break;
878 :
879 : case ZMQ_PLAIN_PASSWORD:
880 0 : if (*optvallen_ >= plain_password.size () + 1) {
881 0 : memcpy (optval_, plain_password.c_str (), plain_password.size () + 1);
882 0 : *optvallen_ = plain_password.size () + 1;
883 0 : return 0;
884 : }
885 : break;
886 :
887 : case ZMQ_ZAP_DOMAIN:
888 0 : if (*optvallen_ >= zap_domain.size () + 1) {
889 0 : memcpy (optval_, zap_domain.c_str (), zap_domain.size () + 1);
890 0 : *optvallen_ = zap_domain.size () + 1;
891 0 : 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 0 : if (is_int) {
899 0 : *value = as_server && mechanism == ZMQ_CURVE;
900 0 : return 0;
901 : }
902 : break;
903 :
904 : case ZMQ_CURVE_PUBLICKEY:
905 0 : if (*optvallen_ == CURVE_KEYSIZE) {
906 0 : memcpy (optval_, curve_public_key, CURVE_KEYSIZE);
907 0 : return 0;
908 : }
909 : else
910 0 : if (*optvallen_ == CURVE_KEYSIZE_Z85 + 1) {
911 0 : zmq_z85_encode ((char *) optval_, curve_public_key, CURVE_KEYSIZE);
912 0 : return 0;
913 : }
914 : break;
915 :
916 : case ZMQ_CURVE_SECRETKEY:
917 0 : if (*optvallen_ == CURVE_KEYSIZE) {
918 0 : memcpy (optval_, curve_secret_key, CURVE_KEYSIZE);
919 0 : return 0;
920 : }
921 : else
922 0 : if (*optvallen_ == CURVE_KEYSIZE_Z85 + 1) {
923 0 : zmq_z85_encode ((char *) optval_, curve_secret_key, CURVE_KEYSIZE);
924 0 : return 0;
925 : }
926 : break;
927 :
928 : case ZMQ_CURVE_SERVERKEY:
929 0 : if (*optvallen_ == CURVE_KEYSIZE) {
930 0 : memcpy (optval_, curve_server_key, CURVE_KEYSIZE);
931 0 : return 0;
932 : }
933 : else
934 0 : if (*optvallen_ == CURVE_KEYSIZE_Z85 + 1) {
935 0 : zmq_z85_encode ((char *) optval_, curve_server_key, CURVE_KEYSIZE);
936 0 : return 0;
937 : }
938 : break;
939 : #endif
940 :
941 : case ZMQ_CONFLATE:
942 0 : if (is_int) {
943 0 : *value = conflate;
944 0 : 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 :
957 : case ZMQ_GSSAPI_PRINCIPAL:
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 :
965 : case ZMQ_GSSAPI_SERVICE_PRINCIPAL:
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 :
973 : case ZMQ_GSSAPI_PLAINTEXT:
974 : if (is_int) {
975 : *value = gss_plaintext;
976 : return 0;
977 : }
978 : break;
979 : #endif
980 :
981 : case ZMQ_HANDSHAKE_IVL:
982 12 : if (is_int) {
983 12 : *value = handshake_ivl;
984 12 : return 0;
985 : }
986 : break;
987 :
988 : case ZMQ_INVERT_MATCHING:
989 0 : if (is_int) {
990 0 : *value = invert_matching;
991 0 : return 0;
992 : }
993 : break;
994 :
995 : case ZMQ_HEARTBEAT_IVL:
996 0 : if (is_int) {
997 0 : *value = heartbeat_interval;
998 0 : return 0;
999 : }
1000 : break;
1001 :
1002 : case ZMQ_HEARTBEAT_TTL:
1003 0 : if (is_int) {
1004 : // Convert the internal deciseconds value to milliseconds
1005 0 : *value = heartbeat_ttl * 100;
1006 0 : return 0;
1007 : }
1008 : break;
1009 :
1010 : case ZMQ_HEARTBEAT_TIMEOUT:
1011 0 : if (is_int) {
1012 0 : *value = heartbeat_timeout;
1013 0 : return 0;
1014 : }
1015 : break;
1016 :
1017 : case ZMQ_USE_FD:
1018 6 : if (is_int) {
1019 6 : *value = use_fd;
1020 6 : 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 0 : errno = EINVAL;
1035 0 : return -1;
1036 : }
1037 :
1038 2613 : bool zmq::options_t::is_valid (int option_) const
1039 : {
1040 : LIBZMQ_UNUSED (option_);
1041 2613 : return true;
1042 : }
|