options.cpp 29.2 KB
Newer Older
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 7 8
    libzmq is free software; you can redistribute it and/or modify it under
    the terms of the GNU Lesser General Public License (LGPL) as published
    by the Free Software Foundation; either version 3 of the License, or
9 10
    (at your option) any later version.

11 12 13 14 15 16 17 18 19 20 21 22 23 24
    As a special exception, the Contributors give you permission to link
    this library with independent modules to produce an executable,
    regardless of the license terms of these independent modules, and to
    copy and distribute the resulting executable under terms of your choice,
    provided that you also meet, for each linked independent module, the
    terms and conditions of the license of that module. An independent
    module is a module which is not derived from or based on this library.
    If you modify this library, you must extend this exception to your
    version of the library.

    libzmq is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
    License for more details.
25

26
    You should have received a copy of the GNU Lesser General Public License
27 28 29
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

30
#include "precompiled.hpp"
31 32
#include <string.h>

33
#include "options.hpp"
34
#include "err.hpp"
35
#include "macros.hpp"
36 37

zmq::options_t::options_t () :
38 39
    sndhwm (1000),
    rcvhwm (1000),
malosek's avatar
malosek committed
40
    affinity (0),
41
    identity_size (0),
42
    rate (100),
43
    recovery_ivl (10000),
44
    multicast_hops (1),
45
    multicast_maxtpdu (1500),
46 47
    sndbuf (-1),
    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 58
    rcvtimeo (-1),
    sndtimeo (-1),
Pieter Hintjens's avatar
Pieter Hintjens committed
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 67 68 69
    tcp_keepalive (-1),
    tcp_keepalive_cnt (-1),
    tcp_keepalive_idle (-1),
    tcp_keepalive_intvl (-1),
70
    mechanism (ZMQ_NULL),
71
    as_server (0),
72
    gss_plaintext (false),
danielkr's avatar
danielkr committed
73
    socket_id (0),
74
    conflate (false),
75
    handshake_ivl (30000),
Jonathan Reams's avatar
Jonathan Reams committed
76 77 78
    connected (false),
    heartbeat_ttl (0),
    heartbeat_interval (0),
79
    heartbeat_timeout (-1),
80
    use_fd (-1)
81
{
82 83 84
    memset (curve_public_key, 0, CURVE_KEYSIZE);
    memset (curve_secret_key, 0, CURVE_KEYSIZE);
    memset (curve_server_key, 0, CURVE_KEYSIZE);
Ilya Kulakov's avatar
Ilya Kulakov committed
85 86 87 88 89 90
#if defined ZMQ_HAVE_VMCI
    vmci_buffer_size = 0;
    vmci_buffer_min_size = 0;
    vmci_buffer_max_size = 0;
    vmci_connect_timeout = -1;
#endif
91
}
92 93 94 95

int zmq::options_t::setsockopt (int option_, const void *optval_,
    size_t optvallen_)
{
96
    bool is_int = (optvallen_ == sizeof (int));
97 98
    int value = 0;
    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 108
                return 0;
            }
109
            break;
110

111
        case ZMQ_RCVHWM:
112
            if (is_int && value >= 0) {
113
                rcvhwm = value;
114 115
                return 0;
            }
116
            break;
117

118
        case ZMQ_AFFINITY:
119
            if (optvallen_ == sizeof (uint64_t)) {
120
                affinity = *((uint64_t*) optval_);
121 122
                return 0;
            }
123 124 125
            break;

        case ZMQ_IDENTITY:
126 127
            //  Identity is any binary string from 1 to 255 octets
            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 138
                return 0;
            }
139
            break;
140

141
        case ZMQ_RECOVERY_IVL:
142
            if (is_int && value >= 0) {
143
                recovery_ivl = value;
144 145 146
                return 0;
            }
            break;
147

148
        case ZMQ_SNDBUF:
149
            if (is_int && value >= -1) {
150
                sndbuf = value;
151 152
                return 0;
            }
153
            break;
154

155
        case ZMQ_RCVBUF:
156
            if (is_int && value >= -1) {
157
                rcvbuf = value;
158 159
                return 0;
            }
160
            break;
161

162 163 164 165 166 167 168
        case ZMQ_TOS:
            if (is_int && value >= 0) {
                tos = value;
                return 0;
            }
            break;

169
        case ZMQ_LINGER:
170
            if (is_int && value >= -1) {
171
                linger = value;
172 173
                return 0;
            }
174
            break;
175

176 177 178 179 180 181 182
        case ZMQ_CONNECT_TIMEOUT:
            if (is_int && value >= 0) {
                connect_timeout = value;
                return 0;
            }
            break;

183
        case ZMQ_TCP_MAXRT:
184
            if (is_int && value >= 0) {
185
                tcp_maxrt = value;
186 187 188 189
                return 0;
            }
            break;

190
        case ZMQ_RECONNECT_IVL:
191
            if (is_int && value >= -1) {
192
                reconnect_ivl = value;
193 194
                return 0;
            }
195
            break;
196

197
        case ZMQ_RECONNECT_IVL_MAX:
198
            if (is_int && value >= 0) {
199
                reconnect_ivl_max = value;
200 201
                return 0;
            }
202
            break;
203

204
        case ZMQ_BACKLOG:
205
            if (is_int && value >= 0) {
206
                backlog = value;
207 208
                return 0;
            }
209
            break;
210

211
        case ZMQ_MAXMSGSIZE:
212
            if (optvallen_ == sizeof (int64_t)) {
213
                maxmsgsize = *((int64_t *) optval_);
214 215
                return 0;
            }
216
            break;
217

218
        case ZMQ_MULTICAST_HOPS:
219
            if (is_int && value > 0) {
220
                multicast_hops = value;
221 222
                return 0;
            }
223
            break;
224

225 226 227 228 229 230 231
        case ZMQ_MULTICAST_MAXTPDU:
            if (is_int && value > 0) {
                multicast_maxtpdu = value;
                return 0;
            }
            break;

232
        case ZMQ_RCVTIMEO:
233
            if (is_int && value >= -1) {
234
                rcvtimeo = value;
235 236
                return 0;
            }
237
            break;
238

239
        case ZMQ_SNDTIMEO:
240
            if (is_int && value >= -1) {
241
                sndtimeo = value;
242 243
                return 0;
            }
244
            break;
245

Pieter Hintjens's avatar
Pieter Hintjens committed
246
        /*  Deprecated in favor of ZMQ_IPV6  */
247
        case ZMQ_IPV4ONLY:
248
            if (is_int && (value == 0 || value == 1)) {
249
                ipv6 = (value == 0);
250 251
                return 0;
            }
252
            break;
253

254 255
        /*  To replace the somewhat surprising IPV4ONLY */
        case ZMQ_IPV6:
256
            if (is_int && (value == 0 || value == 1)) {
257
                ipv6 = (value != 0);
258 259
                return 0;
            }
260
            break;
261

262 263 264 265 266 267 268 269 270 271 272 273 274
        case ZMQ_SOCKS_PROXY:
            if (optval_ == NULL && optvallen_ == 0) {
                socks_proxy_address.clear ();
                return 0;
            }
            else
            if (optval_ != NULL && optvallen_ > 0 ) {
                socks_proxy_address =
                    std::string ((const char *) optval_, optvallen_);
                return 0;
            }
            break;

275
        case ZMQ_TCP_KEEPALIVE:
276
            if (is_int && (value == -1 || value == 0 || value == 1)) {
277
                tcp_keepalive = value;
278 279
                return 0;
            }
280
            break;
281

282
        case ZMQ_TCP_KEEPALIVE_CNT:
283
            if (is_int && (value == -1 || value >= 0)) {
284
                tcp_keepalive_cnt = value;
285 286
                return 0;
            }
287
            break;
288

289
        case ZMQ_TCP_KEEPALIVE_IDLE:
290
            if (is_int && (value == -1 || value >= 0)) {
291
                tcp_keepalive_idle = value;
292 293
                return 0;
            }
294
            break;
295

296
        case ZMQ_TCP_KEEPALIVE_INTVL:
297
            if (is_int && (value == -1 || value >= 0)) {
298
                tcp_keepalive_intvl = value;
299 300
                return 0;
            }
301
            break;
302

303
        case ZMQ_IMMEDIATE:
304
            if (is_int && (value == 0 || value == 1)) {
305
                immediate = value;
306 307
                return 0;
            }
308
            break;
309

310
        case ZMQ_TCP_ACCEPT_FILTER:
311
            if (optvallen_ == 0 && optval_ == NULL) {
312
                tcp_accept_filters.clear ();
313 314
                return 0;
            }
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;
Pieter Hintjens's avatar
Pieter Hintjens committed
319
                int rc = mask.resolve (filter_str.c_str (), ipv6);
320
                if (rc == 0) {
321
                    tcp_accept_filters.push_back (mask);
322 323 324 325
                    return 0;
                }
            }
            break;
326

327
#if defined ZMQ_HAVE_SO_PEERCRED || defined ZMQ_HAVE_LOCAL_PEERCRED
328
        case ZMQ_IPC_FILTER_UID:
329 330 331 332 333 334 335 336 337 338 339
            if (optvallen_ == 0 && optval_ == NULL) {
                ipc_uid_accept_filters.clear ();
                return 0;
            }
            else
            if (optvallen_ == sizeof (uid_t) && optval_ != NULL) {
                ipc_uid_accept_filters.insert (*((uid_t *) optval_));
                return 0;
            }
            break;

340
        case ZMQ_IPC_FILTER_GID:
341 342 343 344 345 346 347 348 349 350
            if (optvallen_ == 0 && optval_ == NULL) {
                ipc_gid_accept_filters.clear ();
                return 0;
            }
            else
            if (optvallen_ == sizeof (gid_t) && optval_ != NULL) {
                ipc_gid_accept_filters.insert (*((gid_t *) optval_));
                return 0;
            }
            break;
351
#endif
352

353
#if defined ZMQ_HAVE_SO_PEERCRED
354
        case ZMQ_IPC_FILTER_PID:
355 356 357 358 359 360 361 362 363 364
            if (optvallen_ == 0 && optval_ == NULL) {
                ipc_pid_accept_filters.clear ();
                return 0;
            }
            else
            if (optvallen_ == sizeof (pid_t) && optval_ != NULL) {
                ipc_pid_accept_filters.insert (*((pid_t *) optval_));
                return 0;
            }
            break;
365
#endif
366

367 368
        case ZMQ_PLAIN_SERVER:
            if (is_int && (value == 0 || value == 1)) {
369
                as_server = value;
370
                mechanism = value? ZMQ_PLAIN: ZMQ_NULL;
371 372 373
                return 0;
            }
            break;
374

375 376 377 378 379 380
        case ZMQ_PLAIN_USERNAME:
            if (optvallen_ == 0 && optval_ == NULL) {
                mechanism = ZMQ_NULL;
                return 0;
            }
            else
381
            if (optvallen_ > 0 && optvallen_ < 256 && optval_ != NULL) {
382
                plain_username.assign ((const char *) optval_, optvallen_);
383
                as_server = 0;
384 385 386 387
                mechanism = ZMQ_PLAIN;
                return 0;
            }
            break;
388

389 390 391 392 393 394
        case ZMQ_PLAIN_PASSWORD:
            if (optvallen_ == 0 && optval_ == NULL) {
                mechanism = ZMQ_NULL;
                return 0;
            }
            else
395
            if (optvallen_ > 0 && optvallen_ < 256 && optval_ != NULL) {
396
                plain_password.assign ((const char *) optval_, optvallen_);
397
                as_server = 0;
398 399
                mechanism = ZMQ_PLAIN;
                return 0;
400
            }
401
            break;
402 403

        case ZMQ_ZAP_DOMAIN:
404
            if (optvallen_ < 256) {
405 406 407 408 409
                zap_domain.assign ((const char *) optval_, optvallen_);
                return 0;
            }
            break;

410 411
        //  If curve encryption isn't built, these options provoke EINVAL
#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 417 418
                return 0;
            }
            break;
419

420
        case ZMQ_CURVE_PUBLICKEY:
421 422 423
            //  TODO: refactor repeated code for these three options
            //  into set_curve_key (destination, optval, optlen) method
            //  ==> set_curve_key (curve_public_key, optval_, optvallen_);
424 425 426 427 428 429
            if (optvallen_ == CURVE_KEYSIZE) {
                memcpy (curve_public_key, optval_, CURVE_KEYSIZE);
                mechanism = ZMQ_CURVE;
                return 0;
            }
            else
430
            if (optvallen_ == CURVE_KEYSIZE_Z85 + 1) {
431 432 433 434
                if (zmq_z85_decode (curve_public_key, (char *) optval_)) {
                    mechanism = ZMQ_CURVE;
                    return 0;
                }
435
            }
436 437 438
            else
            //  Deprecated, not symmetrical with zmq_getsockopt
            if (optvallen_ == CURVE_KEYSIZE_Z85) {
439
                char z85_key [CURVE_KEYSIZE_Z85 + 1];
440 441
                memcpy (z85_key, (char *) optval_, CURVE_KEYSIZE_Z85);
                z85_key [CURVE_KEYSIZE_Z85] = 0;
442 443 444 445
                if (zmq_z85_decode (curve_public_key, z85_key)) {
                    mechanism = ZMQ_CURVE;
                    return 0;
                }
446
            }
447
            break;
448

449 450 451 452 453 454 455
        case ZMQ_CURVE_SECRETKEY:
            if (optvallen_ == CURVE_KEYSIZE) {
                memcpy (curve_secret_key, optval_, CURVE_KEYSIZE);
                mechanism = ZMQ_CURVE;
                return 0;
            }
            else
456
            if (optvallen_ == CURVE_KEYSIZE_Z85 + 1) {
457 458 459 460
                if (zmq_z85_decode (curve_secret_key, (char *) optval_)) {
                    mechanism = ZMQ_CURVE;
                    return 0;
                }
461
            }
462 463 464
            else
            //  Deprecated, not symmetrical with zmq_getsockopt
            if (optvallen_ == CURVE_KEYSIZE_Z85) {
465
                char z85_key [CURVE_KEYSIZE_Z85 + 1];
466 467
                memcpy (z85_key, (char *) optval_, CURVE_KEYSIZE_Z85);
                z85_key [CURVE_KEYSIZE_Z85] = 0;
468 469 470 471
                if (zmq_z85_decode (curve_secret_key, z85_key)) {
                    mechanism = ZMQ_CURVE;
                    return 0;
                }
472
            }
473 474
            break;

475 476 477 478
        case ZMQ_CURVE_SERVERKEY:
            if (optvallen_ == CURVE_KEYSIZE) {
                memcpy (curve_server_key, optval_, CURVE_KEYSIZE);
                mechanism = ZMQ_CURVE;
479
                as_server = 0;
480 481 482
                return 0;
            }
            else
483
            if (optvallen_ == CURVE_KEYSIZE_Z85 + 1) {
484 485 486 487 488
                if (zmq_z85_decode (curve_server_key, (char *) optval_)) {
                    mechanism = ZMQ_CURVE;
                    as_server = 0;
                    return 0;
                }
489 490 491 492
            }
            else
            //  Deprecated, not symmetrical with zmq_getsockopt
            if (optvallen_ == CURVE_KEYSIZE_Z85) {
493
                char z85_key [CURVE_KEYSIZE_Z85 + 1];
494 495
                memcpy (z85_key, (char *) optval_, CURVE_KEYSIZE_Z85);
                z85_key [CURVE_KEYSIZE_Z85] = 0;
496 497 498 499 500
                if (zmq_z85_decode (curve_server_key, z85_key)) {
                    mechanism = ZMQ_CURVE;
                    as_server = 0;
                    return 0;
                }
501
            }
502
            break;
503
#endif
Martin Hurton's avatar
Martin Hurton committed
504

danielkr's avatar
danielkr committed
505 506 507 508 509 510
        case ZMQ_CONFLATE:
            if (is_int && (value == 0 || value == 1)) {
                conflate = (value != 0);
                return 0;
            }
            break;
511 512

        //  If libgssapi isn't installed, these options provoke EINVAL
513
#ifdef HAVE_LIBGSSAPI_KRB5
514 515 516 517 518 519 520
        case ZMQ_GSSAPI_SERVER:
            if (is_int && (value == 0 || value == 1)) {
                as_server = value;
                mechanism = ZMQ_GSSAPI;
                return 0;
            }
            break;
521

Chris Busbey's avatar
Chris Busbey committed
522
        case ZMQ_GSSAPI_PRINCIPAL:
523
            if (optvallen_ > 0 && optvallen_ < 256 && optval_ != NULL) {
Chris Busbey's avatar
Chris Busbey committed
524
                gss_principal.assign ((const char *) optval_, optvallen_);
525 526 527 528 529
                mechanism = ZMQ_GSSAPI;
                return 0;
            }
            break;

Chris Busbey's avatar
Chris Busbey committed
530
        case ZMQ_GSSAPI_SERVICE_PRINCIPAL:
531
            if (optvallen_ > 0 && optvallen_ < 256 && optval_ != NULL) {
Chris Busbey's avatar
Chris Busbey committed
532
                gss_service_principal.assign ((const char *) optval_, optvallen_);
533
                mechanism = ZMQ_GSSAPI;
Chris Busbey's avatar
Chris Busbey committed
534
                as_server = 0;
535 536 537
                return 0;
            }
            break;
danielkr's avatar
danielkr committed
538

539 540 541 542 543 544
        case ZMQ_GSSAPI_PLAINTEXT:
            if (is_int && (value == 0 || value == 1)) {
                gss_plaintext = (value != 0);
                return 0;
            }
            break;
545
#endif
546

547 548 549 550 551 552 553
        case ZMQ_HANDSHAKE_IVL:
            if (is_int && value >= 0) {
                handshake_ivl = value;
                return 0;
            }
            break;

554 555 556 557 558 559 560
        case ZMQ_INVERT_MATCHING:
            if (is_int) {
                invert_matching = (value != 0);
                return 0;
            }
            break;

Jonathan Reams's avatar
Jonathan Reams committed
561 562 563 564 565 566 567 568
        case ZMQ_HEARTBEAT_IVL:
            if (is_int && value >= 0) {
                heartbeat_interval = value;
                return 0;
            }
            break;

        case ZMQ_HEARTBEAT_TTL:
569 570 571
            // Convert this to deciseconds from milliseconds
            value = value / 100;
            if (is_int && value >= 0 && value <= 6553) {
Jonathan Reams's avatar
Jonathan Reams committed
572 573 574 575 576 577 578 579 580 581 582 583
                heartbeat_ttl = (uint16_t)value;
                return 0;
            }
            break;

        case ZMQ_HEARTBEAT_TIMEOUT:
            if (is_int && value >= 0) {
                heartbeat_timeout = value;
                return 0;
            }
            break;

584
#ifdef ZMQ_HAVE_VMCI
Ilya Kulakov's avatar
Ilya Kulakov committed
585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611
        case ZMQ_VMCI_BUFFER_SIZE:
            if (optvallen_ == sizeof (uint64_t)) {
                vmci_buffer_size = *((uint64_t*) optval_);
                return 0;
            }
            break;

        case ZMQ_VMCI_BUFFER_MIN_SIZE:
            if (optvallen_ == sizeof (uint64_t)) {
                vmci_buffer_min_size = *((uint64_t*) optval_);
                return 0;
            }
            break;

        case ZMQ_VMCI_BUFFER_MAX_SIZE:
            if (optvallen_ == sizeof (uint64_t)) {
                vmci_buffer_max_size = *((uint64_t*) optval_);
                return 0;
            }
            break;

        case ZMQ_VMCI_CONNECT_TIMEOUT:
            if (optvallen_ == sizeof (int)) {
                vmci_connect_timeout = *((int*) optval_);
                return 0;
            }
            break;
612
#endif
Ilya Kulakov's avatar
Ilya Kulakov committed
613

614
        case ZMQ_USE_FD:
615
            if (is_int && value >= -1) {
616
                use_fd = value;
617 618 619 620
                return 0;
            }
            break;

danielkr's avatar
danielkr committed
621
        default:
622
#if defined (ZMQ_ACT_MILITANT)
623 624 625 626 627
            //  There are valid scenarios for probing with unknown socket option
            //  values, e.g. to check if security is enabled or not. This will not
            //  provoke a militant assert. However, passing bad values to a valid
            //  socket option will, if ZMQ_ACT_MILITANT is defined.
            malformed = false;
628
#endif
danielkr's avatar
danielkr committed
629
            break;
630
    }
631 632 633 634 635 636 637
#if defined (ZMQ_ACT_MILITANT)
    //  There is no valid use case for passing an error back to the application
    //  when it sent malformed arguments to a socket option. Use ./configure
    //  --with-militant to enable this checking.
    if (malformed)
        zmq_assert (false);
#endif
638 639
    errno = EINVAL;
    return -1;
640
}
641

642
int zmq::options_t::getsockopt (int option_, void *optval_, size_t *optvallen_) const
643
{
644 645
    bool is_int = (*optvallen_ == sizeof (int));
    int *value = (int *) optval_;
646 647 648
#if defined (ZMQ_ACT_MILITANT)
    bool malformed = true;          //  Did caller pass a bad option value?
#endif
649

650
    switch (option_) {
651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707
        case ZMQ_SNDHWM:
            if (is_int) {
                *value = sndhwm;
                return 0;
            }
            break;

        case ZMQ_RCVHWM:
            if (is_int) {
                *value = rcvhwm;
                return 0;
            }
            break;

        case ZMQ_AFFINITY:
            if (*optvallen_ == sizeof (uint64_t)) {
                *((uint64_t *) optval_) = affinity;
                return 0;
            }
            break;

        case ZMQ_IDENTITY:
            if (*optvallen_ >= identity_size) {
                memcpy (optval_, identity, identity_size);
                *optvallen_ = identity_size;
                return 0;
            }
            break;

        case ZMQ_RATE:
            if (is_int) {
                *value = rate;
                return 0;
            }
            break;

        case ZMQ_RECOVERY_IVL:
            if (is_int) {
                *value = recovery_ivl;
                return 0;
            }
            break;

        case ZMQ_SNDBUF:
            if (is_int) {
                *value = sndbuf;
                return 0;
            }
            break;

        case ZMQ_RCVBUF:
            if (is_int) {
                *value = rcvbuf;
                return 0;
            }
            break;

708 709 710 711 712 713
        case ZMQ_TOS:
            if (is_int) {
                *value = tos;
                return 0;
            }
            break;
Martin Hurton's avatar
Martin Hurton committed
714

715 716 717 718 719 720 721 722 723 724 725 726 727
        case ZMQ_TYPE:
            if (is_int) {
                *value = type;
                return 0;
            }
            break;

        case ZMQ_LINGER:
            if (is_int) {
                *value = linger;
                return 0;
            }
            break;
728

729 730 731 732 733 734 735
        case ZMQ_CONNECT_TIMEOUT:
            if (is_int) {
                *value = connect_timeout;
                return 0;
            }
            break;

736
        case ZMQ_TCP_MAXRT:
737
            if (is_int) {
738
                *value = tcp_maxrt;
739 740 741 742
                return 0;
            }
            break;

743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778
        case ZMQ_RECONNECT_IVL:
            if (is_int) {
                *value = reconnect_ivl;
                return 0;
            }
            break;

        case ZMQ_RECONNECT_IVL_MAX:
            if (is_int) {
                *value = reconnect_ivl_max;
                return 0;
            }
            break;

        case ZMQ_BACKLOG:
            if (is_int) {
                *value = backlog;
                return 0;
            }
            break;

        case ZMQ_MAXMSGSIZE:
            if (*optvallen_ == sizeof (int64_t)) {
                *((int64_t *) optval_) = maxmsgsize;
                *optvallen_ = sizeof (int64_t);
                return 0;
            }
            break;

        case ZMQ_MULTICAST_HOPS:
            if (is_int) {
                *value = multicast_hops;
                return 0;
            }
            break;

779 780 781 782 783 784 785
        case ZMQ_MULTICAST_MAXTPDU:
            if (is_int) {
                *value = multicast_maxtpdu;
                return 0;
            }
            break;

786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805
        case ZMQ_RCVTIMEO:
            if (is_int) {
                *value = rcvtimeo;
                return 0;
            }
            break;

        case ZMQ_SNDTIMEO:
            if (is_int) {
                *value = sndtimeo;
                return 0;
            }
            break;

        case ZMQ_IPV4ONLY:
            if (is_int) {
                *value = 1 - ipv6;
                return 0;
            }
            break;
806

807 808 809 810 811 812 813 814 815 816 817 818 819 820
        case ZMQ_IPV6:
            if (is_int) {
                *value = ipv6;
                return 0;
            }
            break;

        case ZMQ_IMMEDIATE:
            if (is_int) {
                *value = immediate;
                return 0;
            }
            break;

821 822 823 824 825 826 827 828
        case ZMQ_SOCKS_PROXY:
            if (*optvallen_ >= socks_proxy_address.size () + 1) {
                memcpy (optval_, socks_proxy_address.c_str (), socks_proxy_address.size () + 1);
                *optvallen_ = socks_proxy_address.size () + 1;
                return 0;
            }
            break;

829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862
        case ZMQ_TCP_KEEPALIVE:
            if (is_int) {
                *value = tcp_keepalive;
                return 0;
            }
            break;

        case ZMQ_TCP_KEEPALIVE_CNT:
            if (is_int) {
                *value = tcp_keepalive_cnt;
                return 0;
            }
            break;

        case ZMQ_TCP_KEEPALIVE_IDLE:
            if (is_int) {
                *value = tcp_keepalive_idle;
                return 0;
            }
            break;

        case ZMQ_TCP_KEEPALIVE_INTVL:
            if (is_int) {
                *value = tcp_keepalive_intvl;
                return 0;
            }
            break;

        case ZMQ_MECHANISM:
            if (is_int) {
                *value = mechanism;
                return 0;
            }
            break;
863

864
        case ZMQ_PLAIN_SERVER:
865
            if (is_int) {
866
                *value = as_server && mechanism == ZMQ_PLAIN;
867 868 869
                return 0;
            }
            break;
870

871 872 873 874 875 876 877
        case ZMQ_PLAIN_USERNAME:
            if (*optvallen_ >= plain_username.size () + 1) {
                memcpy (optval_, plain_username.c_str (), plain_username.size () + 1);
                *optvallen_ = plain_username.size () + 1;
                return 0;
            }
            break;
878

879 880 881 882 883 884 885
        case ZMQ_PLAIN_PASSWORD:
            if (*optvallen_ >= plain_password.size () + 1) {
                memcpy (optval_, plain_password.c_str (), plain_password.size () + 1);
                *optvallen_ = plain_password.size () + 1;
                return 0;
            }
            break;
886 887 888 889 890 891 892 893 894

        case ZMQ_ZAP_DOMAIN:
            if (*optvallen_ >= zap_domain.size () + 1) {
                memcpy (optval_, zap_domain.c_str (), zap_domain.size () + 1);
                *optvallen_ = zap_domain.size () + 1;
                return 0;
            }
            break;

895 896
        //  If curve encryption isn't built, these options provoke EINVAL
#ifdef ZMQ_HAVE_CURVE
897
        case ZMQ_CURVE_SERVER:
898
            if (is_int) {
899
                *value = as_server && mechanism == ZMQ_CURVE;
900 901 902
                return 0;
            }
            break;
903

904 905 906 907 908 909 910 911 912 913
        case ZMQ_CURVE_PUBLICKEY:
            if (*optvallen_ == CURVE_KEYSIZE) {
                memcpy (optval_, curve_public_key, CURVE_KEYSIZE);
                return 0;
            }
            else
            if (*optvallen_ == CURVE_KEYSIZE_Z85 + 1) {
                zmq_z85_encode ((char *) optval_, curve_public_key, CURVE_KEYSIZE);
                return 0;
            }
914
            break;
915

916 917 918 919 920 921 922 923 924 925
        case ZMQ_CURVE_SECRETKEY:
            if (*optvallen_ == CURVE_KEYSIZE) {
                memcpy (optval_, curve_secret_key, CURVE_KEYSIZE);
                return 0;
            }
            else
            if (*optvallen_ == CURVE_KEYSIZE_Z85 + 1) {
                zmq_z85_encode ((char *) optval_, curve_secret_key, CURVE_KEYSIZE);
                return 0;
            }
926 927
            break;

928 929 930 931 932 933 934 935 936 937
        case ZMQ_CURVE_SERVERKEY:
            if (*optvallen_ == CURVE_KEYSIZE) {
                memcpy (optval_, curve_server_key, CURVE_KEYSIZE);
                return 0;
            }
            else
            if (*optvallen_ == CURVE_KEYSIZE_Z85 + 1) {
                zmq_z85_encode ((char *) optval_, curve_server_key, CURVE_KEYSIZE);
                return 0;
            }
938
            break;
939
#endif
danielkr's avatar
danielkr committed
940 941 942 943 944 945 946

        case ZMQ_CONFLATE:
            if (is_int) {
                *value = conflate;
                return 0;
            }
            break;
Martin Hurton's avatar
Martin Hurton committed
947

948
        //  If libgssapi isn't installed, these options provoke EINVAL
949
#ifdef HAVE_LIBGSSAPI_KRB5
950 951 952 953 954 955
        case ZMQ_GSSAPI_SERVER:
            if (is_int) {
                *value = as_server && mechanism == ZMQ_GSSAPI;
                return 0;
            }
            break;
956

Chris Busbey's avatar
Chris Busbey committed
957 958 959 960
        case ZMQ_GSSAPI_PRINCIPAL:
            if (*optvallen_ >= gss_principal.size () + 1) {
                memcpy (optval_, gss_principal.c_str (), gss_principal.size () + 1);
                *optvallen_ = gss_principal.size () + 1;
961 962 963
                return 0;
            }
            break;
danielkr's avatar
danielkr committed
964

Chris Busbey's avatar
Chris Busbey committed
965 966 967 968
        case ZMQ_GSSAPI_SERVICE_PRINCIPAL:
            if (*optvallen_ >= gss_service_principal.size () + 1) {
                memcpy (optval_, gss_service_principal.c_str (), gss_service_principal.size () + 1);
                *optvallen_ = gss_service_principal.size () + 1;
969 970 971
                return 0;
            }
            break;
972

973 974 975 976 977 978
        case ZMQ_GSSAPI_PLAINTEXT:
            if (is_int) {
                *value = gss_plaintext;
                return 0;
            }
            break;
979 980
#endif

981 982 983 984 985 986
        case ZMQ_HANDSHAKE_IVL:
            if (is_int) {
                *value = handshake_ivl;
                return 0;
            }
            break;
987

988 989 990 991 992 993 994
        case ZMQ_INVERT_MATCHING:
            if (is_int) {
                *value = invert_matching;
                return 0;
            }
            break;

Jonathan Reams's avatar
Jonathan Reams committed
995 996 997 998 999 1000 1001 1002 1003
        case ZMQ_HEARTBEAT_IVL:
            if (is_int) {
                *value = heartbeat_interval;
                return 0;
            }
            break;

        case ZMQ_HEARTBEAT_TTL:
            if (is_int) {
1004 1005
                // Convert the internal deciseconds value to milliseconds
                *value = heartbeat_ttl * 100;
Jonathan Reams's avatar
Jonathan Reams committed
1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016
                return 0;
            }
            break;

        case ZMQ_HEARTBEAT_TIMEOUT:
            if (is_int) {
                *value = heartbeat_timeout;
                return 0;
            }
            break;

1017
        case ZMQ_USE_FD:
1018
            if (is_int) {
1019
                *value = use_fd;
1020 1021 1022 1023
                return 0;
            }
            break;

1024 1025 1026 1027 1028
        default:
#if defined (ZMQ_ACT_MILITANT)
            malformed = false;
#endif
            break;
1029
    }
1030 1031 1032 1033
#if defined (ZMQ_ACT_MILITANT)
    if (malformed)
        zmq_assert (false);
#endif
1034 1035 1036
    errno = EINVAL;
    return -1;
}
1037 1038 1039

bool zmq::options_t::is_valid (int option_) const
{
1040
    LIBZMQ_UNUSED (option_);
1041
    return true;
1042
}