Coverage Report

Created: 2025-11-30 06:32

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libzmq/src/options.cpp
Line
Count
Source
1
/* SPDX-License-Identifier: MPL-2.0 */
2
3
#include "precompiled.hpp"
4
#include <string.h>
5
#include <limits.h>
6
#include <set>
7
8
#include "options.hpp"
9
#include "err.hpp"
10
#include "macros.hpp"
11
12
#ifndef ZMQ_HAVE_WINDOWS
13
#include <net/if.h>
14
#endif
15
16
#if defined IFNAMSIZ
17
0
#define BINDDEVSIZ IFNAMSIZ
18
#else
19
#define BINDDEVSIZ 16
20
#endif
21
22
static int sockopt_invalid ()
23
0
{
24
#if defined(ZMQ_ACT_MILITANT)
25
    zmq_assert (false);
26
#endif
27
0
    errno = EINVAL;
28
0
    return -1;
29
0
}
30
31
int zmq::do_getsockopt (void *const optval_,
32
                        size_t *const optvallen_,
33
                        const std::string &value_)
34
0
{
35
0
    return do_getsockopt (optval_, optvallen_, value_.c_str (),
36
0
                          value_.size () + 1);
37
0
}
38
39
int zmq::do_getsockopt (void *const optval_,
40
                        size_t *const optvallen_,
41
                        const void *value_,
42
                        const size_t value_len_)
43
0
{
44
    // TODO behaviour is inconsistent with options_t::getsockopt; there, an
45
    // *exact* length match is required except for string-like (but not the
46
    // CURVE keys!) (and therefore null-ing remaining memory is a no-op, see
47
    // comment below)
48
0
    if (*optvallen_ < value_len_) {
49
0
        return sockopt_invalid ();
50
0
    }
51
0
    memcpy (optval_, value_, value_len_);
52
    // TODO why is the remaining memory null-ed?
53
0
    memset (static_cast<char *> (optval_) + value_len_, 0,
54
0
            *optvallen_ - value_len_);
55
0
    *optvallen_ = value_len_;
56
0
    return 0;
57
0
}
58
59
#ifdef ZMQ_HAVE_CURVE
60
static int do_getsockopt_curve_key (void *const optval_,
61
                                    const size_t *const optvallen_,
62
                                    const uint8_t (&curve_key_)[CURVE_KEYSIZE])
63
0
{
64
0
    if (*optvallen_ == CURVE_KEYSIZE) {
65
0
        memcpy (optval_, curve_key_, CURVE_KEYSIZE);
66
0
        return 0;
67
0
    }
68
0
    if (*optvallen_ == CURVE_KEYSIZE_Z85 + 1) {
69
0
        zmq_z85_encode (static_cast<char *> (optval_), curve_key_,
70
0
                        CURVE_KEYSIZE);
71
0
        return 0;
72
0
    }
73
0
    return sockopt_invalid ();
74
0
}
75
#endif
76
77
template <typename T>
78
static int do_setsockopt (const void *const optval_,
79
                          const size_t optvallen_,
80
                          T *const out_value_)
81
0
{
82
0
    if (optvallen_ == sizeof (T)) {
83
0
        memcpy (out_value_, optval_, sizeof (T));
84
0
        return 0;
85
0
    }
86
0
    return sockopt_invalid ();
87
0
}
Unexecuted instantiation: options.cpp:int do_setsockopt<int>(void const*, unsigned long, int*)
Unexecuted instantiation: options.cpp:int do_setsockopt<unsigned long>(void const*, unsigned long, unsigned long*)
Unexecuted instantiation: options.cpp:int do_setsockopt<long>(void const*, unsigned long, long*)
88
89
int zmq::do_setsockopt_int_as_bool_strict (const void *const optval_,
90
                                           const size_t optvallen_,
91
                                           bool *const out_value_)
92
0
{
93
    // TODO handling of values other than 0 or 1 is not consistent,
94
    // here it is disallowed, but for other options such as
95
    // ZMQ_ROUTER_RAW any positive value is accepted
96
0
    int value = -1;
97
0
    if (do_setsockopt (optval_, optvallen_, &value) == -1)
98
0
        return -1;
99
0
    if (value == 0 || value == 1) {
100
0
        *out_value_ = (value != 0);
101
0
        return 0;
102
0
    }
103
0
    return sockopt_invalid ();
104
0
}
105
106
int zmq::do_setsockopt_int_as_bool_relaxed (const void *const optval_,
107
                                            const size_t optvallen_,
108
                                            bool *const out_value_)
109
0
{
110
0
    int value = -1;
111
0
    if (do_setsockopt (optval_, optvallen_, &value) == -1)
112
0
        return -1;
113
0
    *out_value_ = (value != 0);
114
0
    return 0;
115
0
}
116
117
static int
118
do_setsockopt_string_allow_empty_strict (const void *const optval_,
119
                                         const size_t optvallen_,
120
                                         std::string *const out_value_,
121
                                         const size_t max_len_)
122
0
{
123
    // TODO why is optval_ != NULL not allowed in case of optvallen_== 0?
124
    // TODO why are empty strings allowed for some socket options, but not for others?
125
0
    if (optval_ == NULL && optvallen_ == 0) {
126
0
        out_value_->clear ();
127
0
        return 0;
128
0
    }
129
0
    if (optval_ != NULL && optvallen_ > 0 && optvallen_ <= max_len_) {
130
0
        out_value_->assign (static_cast<const char *> (optval_), optvallen_);
131
0
        return 0;
132
0
    }
133
0
    return sockopt_invalid ();
134
0
}
135
136
static int
137
do_setsockopt_string_allow_empty_relaxed (const void *const optval_,
138
                                          const size_t optvallen_,
139
                                          std::string *const out_value_,
140
                                          const size_t max_len_)
141
0
{
142
    // TODO use either do_setsockopt_string_allow_empty_relaxed or
143
    // do_setsockopt_string_allow_empty_strict everywhere
144
0
    if (optvallen_ > 0 && optvallen_ <= max_len_) {
145
0
        out_value_->assign (static_cast<const char *> (optval_), optvallen_);
146
0
        return 0;
147
0
    }
148
0
    return sockopt_invalid ();
149
0
}
150
151
template <typename T>
152
static int do_setsockopt_set (const void *const optval_,
153
                              const size_t optvallen_,
154
                              std::set<T> *const set_)
155
0
{
156
0
    if (optvallen_ == 0 && optval_ == NULL) {
157
0
        set_->clear ();
158
0
        return 0;
159
0
    }
160
0
    if (optvallen_ == sizeof (T) && optval_ != NULL) {
161
0
        set_->insert (*(static_cast<const T *> (optval_)));
162
0
        return 0;
163
0
    }
164
0
    return sockopt_invalid ();
165
0
}
Unexecuted instantiation: options.cpp:int do_setsockopt_set<unsigned int>(void const*, unsigned long, std::__1::set<unsigned int, std::__1::less<unsigned int>, std::__1::allocator<unsigned int> >*)
Unexecuted instantiation: options.cpp:int do_setsockopt_set<int>(void const*, unsigned long, std::__1::set<int, std::__1::less<int>, std::__1::allocator<int> >*)
166
167
// TODO why is 1000 a sensible default?
168
const int default_hwm = 1000;
169
170
zmq::options_t::options_t () :
171
0
    sndhwm (default_hwm),
172
0
    rcvhwm (default_hwm),
173
0
    affinity (0),
174
0
    routing_id_size (0),
175
0
    rate (100),
176
0
    recovery_ivl (10000),
177
0
    multicast_hops (1),
178
0
    multicast_maxtpdu (1500),
179
0
    sndbuf (-1),
180
0
    rcvbuf (-1),
181
0
    tos (0),
182
0
    priority (0),
183
0
    type (-1),
184
0
    linger (-1),
185
0
    connect_timeout (0),
186
0
    tcp_maxrt (0),
187
0
    reconnect_stop (0),
188
0
    reconnect_ivl (100),
189
0
    reconnect_ivl_max (0),
190
0
    backlog (100),
191
0
    maxmsgsize (-1),
192
0
    rcvtimeo (-1),
193
0
    sndtimeo (-1),
194
0
    ipv6 (false),
195
0
    immediate (0),
196
0
    filter (false),
197
0
    invert_matching (false),
198
0
    recv_routing_id (false),
199
0
    raw_socket (false),
200
0
    raw_notify (true),
201
0
    tcp_keepalive (-1),
202
0
    tcp_keepalive_cnt (-1),
203
0
    tcp_keepalive_idle (-1),
204
0
    tcp_keepalive_intvl (-1),
205
0
    mechanism (ZMQ_NULL),
206
0
    as_server (0),
207
0
    gss_principal_nt (ZMQ_GSSAPI_NT_HOSTBASED),
208
0
    gss_service_principal_nt (ZMQ_GSSAPI_NT_HOSTBASED),
209
0
    gss_plaintext (false),
210
0
    socket_id (0),
211
0
    conflate (false),
212
0
    handshake_ivl (30000),
213
0
    connected (false),
214
0
    heartbeat_ttl (0),
215
0
    heartbeat_interval (0),
216
0
    heartbeat_timeout (-1),
217
0
    use_fd (-1),
218
0
    zap_enforce_domain (false),
219
0
    loopback_fastpath (false),
220
0
    multicast_loop (true),
221
0
    in_batch_size (8192),
222
0
    out_batch_size (8192),
223
0
    zero_copy (true),
224
0
    router_notify (0),
225
0
    monitor_event_version (1),
226
0
    wss_trust_system (false),
227
0
    hello_msg (),
228
0
    can_send_hello_msg (false),
229
0
    disconnect_msg (),
230
0
    can_recv_disconnect_msg (false),
231
0
    hiccup_msg (),
232
0
    can_recv_hiccup_msg (false),
233
0
    norm_mode (ZMQ_NORM_CC),
234
0
    norm_unicast_nacks (false),
235
0
    norm_buffer_size (2048),
236
0
    norm_segment_size (1400),
237
0
    norm_block_size (16),
238
0
    norm_num_parity (4),
239
0
    norm_num_autoparity (0),
240
0
    norm_push_enable (false),
241
0
    busy_poll (0)
242
0
{
243
0
    memset (curve_public_key, 0, CURVE_KEYSIZE);
244
0
    memset (curve_secret_key, 0, CURVE_KEYSIZE);
245
0
    memset (curve_server_key, 0, CURVE_KEYSIZE);
246
#if defined ZMQ_HAVE_VMCI
247
    vmci_buffer_size = 0;
248
    vmci_buffer_min_size = 0;
249
    vmci_buffer_max_size = 0;
250
    vmci_connect_timeout = -1;
251
#endif
252
0
}
253
254
int zmq::options_t::set_curve_key (uint8_t *destination_,
255
                                   const void *optval_,
256
                                   size_t optvallen_)
257
0
{
258
0
    switch (optvallen_) {
259
0
        case CURVE_KEYSIZE:
260
0
            memcpy (destination_, optval_, optvallen_);
261
0
            mechanism = ZMQ_CURVE;
262
0
            return 0;
263
264
0
        case CURVE_KEYSIZE_Z85 + 1: {
265
0
            const std::string s (static_cast<const char *> (optval_),
266
0
                                 optvallen_);
267
268
0
            if (zmq_z85_decode (destination_, s.c_str ())) {
269
0
                mechanism = ZMQ_CURVE;
270
0
                return 0;
271
0
            }
272
0
            break;
273
0
        }
274
275
0
        case CURVE_KEYSIZE_Z85:
276
0
            char z85_key[CURVE_KEYSIZE_Z85 + 1];
277
0
            memcpy (z85_key, reinterpret_cast<const char *> (optval_),
278
0
                    optvallen_);
279
0
            z85_key[CURVE_KEYSIZE_Z85] = 0;
280
0
            if (zmq_z85_decode (destination_, z85_key)) {
281
0
                mechanism = ZMQ_CURVE;
282
0
                return 0;
283
0
            }
284
0
            break;
285
286
0
        default:
287
0
            break;
288
0
    }
289
0
    return -1;
290
0
}
291
292
const int deciseconds_per_millisecond = 100;
293
294
int zmq::options_t::setsockopt (int option_,
295
                                const void *optval_,
296
                                size_t optvallen_)
297
0
{
298
0
    const bool is_int = (optvallen_ == sizeof (int));
299
0
    int value = 0;
300
0
    if (is_int)
301
0
        memcpy (&value, optval_, sizeof (int));
302
#if defined(ZMQ_ACT_MILITANT)
303
    bool malformed = true; //  Did caller pass a bad option value?
304
#endif
305
306
0
    switch (option_) {
307
0
        case ZMQ_SNDHWM:
308
0
            if (is_int && value >= 0) {
309
0
                sndhwm = value;
310
0
                return 0;
311
0
            }
312
0
            break;
313
314
0
        case ZMQ_RCVHWM:
315
0
            if (is_int && value >= 0) {
316
0
                rcvhwm = value;
317
0
                return 0;
318
0
            }
319
0
            break;
320
321
0
        case ZMQ_AFFINITY:
322
0
            return do_setsockopt (optval_, optvallen_, &affinity);
323
324
0
        case ZMQ_ROUTING_ID:
325
            //  Routing id is any binary string from 1 to 255 octets
326
0
            if (optvallen_ > 0 && optvallen_ <= UCHAR_MAX) {
327
0
                routing_id_size = static_cast<unsigned char> (optvallen_);
328
0
                memcpy (routing_id, optval_, routing_id_size);
329
0
                return 0;
330
0
            }
331
0
            break;
332
333
0
        case ZMQ_RATE:
334
0
            if (is_int && value > 0) {
335
0
                rate = value;
336
0
                return 0;
337
0
            }
338
0
            break;
339
340
0
        case ZMQ_RECOVERY_IVL:
341
0
            if (is_int && value >= 0) {
342
0
                recovery_ivl = value;
343
0
                return 0;
344
0
            }
345
0
            break;
346
347
0
        case ZMQ_SNDBUF:
348
0
            if (is_int && value >= -1) {
349
0
                sndbuf = value;
350
0
                return 0;
351
0
            }
352
0
            break;
353
354
0
        case ZMQ_RCVBUF:
355
0
            if (is_int && value >= -1) {
356
0
                rcvbuf = value;
357
0
                return 0;
358
0
            }
359
0
            break;
360
361
0
        case ZMQ_TOS:
362
0
            if (is_int && value >= 0) {
363
0
                tos = value;
364
0
                return 0;
365
0
            }
366
0
            break;
367
368
0
        case ZMQ_LINGER:
369
0
            if (is_int && value >= -1) {
370
0
                linger.store (value);
371
0
                return 0;
372
0
            }
373
0
            break;
374
375
0
        case ZMQ_CONNECT_TIMEOUT:
376
0
            if (is_int && value >= 0) {
377
0
                connect_timeout = value;
378
0
                return 0;
379
0
            }
380
0
            break;
381
382
0
        case ZMQ_TCP_MAXRT:
383
0
            if (is_int && value >= 0) {
384
0
                tcp_maxrt = value;
385
0
                return 0;
386
0
            }
387
0
            break;
388
389
0
        case ZMQ_RECONNECT_STOP:
390
0
            if (is_int) {
391
0
                reconnect_stop = value;
392
0
                return 0;
393
0
            }
394
0
            break;
395
396
0
        case ZMQ_RECONNECT_IVL:
397
0
            if (is_int && value >= -1) {
398
0
                reconnect_ivl = value;
399
0
                return 0;
400
0
            }
401
0
            break;
402
403
0
        case ZMQ_RECONNECT_IVL_MAX:
404
0
            if (is_int && value >= 0) {
405
0
                reconnect_ivl_max = value;
406
0
                return 0;
407
0
            }
408
0
            break;
409
410
0
        case ZMQ_BACKLOG:
411
0
            if (is_int && value >= 0) {
412
0
                backlog = value;
413
0
                return 0;
414
0
            }
415
0
            break;
416
417
0
        case ZMQ_MAXMSGSIZE:
418
0
            return do_setsockopt (optval_, optvallen_, &maxmsgsize);
419
420
0
        case ZMQ_MULTICAST_HOPS:
421
0
            if (is_int && value > 0) {
422
0
                multicast_hops = value;
423
0
                return 0;
424
0
            }
425
0
            break;
426
427
0
        case ZMQ_MULTICAST_MAXTPDU:
428
0
            if (is_int && value > 0) {
429
0
                multicast_maxtpdu = value;
430
0
                return 0;
431
0
            }
432
0
            break;
433
434
0
        case ZMQ_RCVTIMEO:
435
0
            if (is_int && value >= -1) {
436
0
                rcvtimeo = value;
437
0
                return 0;
438
0
            }
439
0
            break;
440
441
0
        case ZMQ_SNDTIMEO:
442
0
            if (is_int && value >= -1) {
443
0
                sndtimeo = value;
444
0
                return 0;
445
0
            }
446
0
            break;
447
448
        /*  Deprecated in favor of ZMQ_IPV6  */
449
0
        case ZMQ_IPV4ONLY: {
450
0
            bool value;
451
0
            const int rc =
452
0
              do_setsockopt_int_as_bool_strict (optval_, optvallen_, &value);
453
0
            if (rc == 0)
454
0
                ipv6 = !value;
455
0
            return rc;
456
0
        }
457
458
        /*  To replace the somewhat surprising IPV4ONLY */
459
0
        case ZMQ_IPV6:
460
0
            return do_setsockopt_int_as_bool_strict (optval_, optvallen_,
461
0
                                                     &ipv6);
462
463
0
        case ZMQ_SOCKS_PROXY:
464
0
            return do_setsockopt_string_allow_empty_strict (
465
0
              optval_, optvallen_, &socks_proxy_address, SIZE_MAX);
466
467
0
        case ZMQ_SOCKS_USERNAME:
468
            /* Make empty string or NULL equivalent. */
469
0
            if (optval_ == NULL || optvallen_ == 0) {
470
0
                socks_proxy_username.clear ();
471
0
                return 0;
472
0
            } else {
473
0
                return do_setsockopt_string_allow_empty_strict (
474
0
                  optval_, optvallen_, &socks_proxy_username, 255);
475
0
            }
476
0
        case ZMQ_SOCKS_PASSWORD:
477
            /* Make empty string or NULL equivalent. */
478
0
            if (optval_ == NULL || optvallen_ == 0) {
479
0
                socks_proxy_password.clear ();
480
0
                return 0;
481
0
            } else {
482
0
                return do_setsockopt_string_allow_empty_strict (
483
0
                  optval_, optvallen_, &socks_proxy_password, 255);
484
0
            }
485
0
        case ZMQ_TCP_KEEPALIVE:
486
0
            if (is_int && (value == -1 || value == 0 || value == 1)) {
487
0
                tcp_keepalive = value;
488
0
                return 0;
489
0
            }
490
0
            break;
491
492
0
        case ZMQ_TCP_KEEPALIVE_CNT:
493
0
            if (is_int && (value == -1 || value >= 0)) {
494
0
                tcp_keepalive_cnt = value;
495
0
                return 0;
496
0
            }
497
0
            break;
498
499
0
        case ZMQ_TCP_KEEPALIVE_IDLE:
500
0
            if (is_int && (value == -1 || value >= 0)) {
501
0
                tcp_keepalive_idle = value;
502
0
                return 0;
503
0
            }
504
0
            break;
505
506
0
        case ZMQ_TCP_KEEPALIVE_INTVL:
507
0
            if (is_int && (value == -1 || value >= 0)) {
508
0
                tcp_keepalive_intvl = value;
509
0
                return 0;
510
0
            }
511
0
            break;
512
513
0
        case ZMQ_IMMEDIATE:
514
            // TODO why is immediate not bool (and called non_immediate, as its meaning appears to be reversed)
515
0
            if (is_int && (value == 0 || value == 1)) {
516
0
                immediate = value;
517
0
                return 0;
518
0
            }
519
0
            break;
520
521
0
        case ZMQ_TCP_ACCEPT_FILTER: {
522
0
            std::string filter_str;
523
0
            int rc = do_setsockopt_string_allow_empty_strict (
524
0
              optval_, optvallen_, &filter_str, UCHAR_MAX);
525
0
            if (rc == 0) {
526
0
                if (filter_str.empty ()) {
527
0
                    tcp_accept_filters.clear ();
528
0
                } else {
529
0
                    tcp_address_mask_t mask;
530
0
                    rc = mask.resolve (filter_str.c_str (), ipv6);
531
0
                    if (rc == 0) {
532
0
                        tcp_accept_filters.push_back (mask);
533
0
                    }
534
0
                }
535
0
            }
536
0
            return rc;
537
0
        }
538
539
0
#if defined ZMQ_HAVE_SO_PEERCRED || defined ZMQ_HAVE_LOCAL_PEERCRED
540
0
        case ZMQ_IPC_FILTER_UID:
541
0
            return do_setsockopt_set (optval_, optvallen_,
542
0
                                      &ipc_uid_accept_filters);
543
544
545
0
        case ZMQ_IPC_FILTER_GID:
546
0
            return do_setsockopt_set (optval_, optvallen_,
547
0
                                      &ipc_gid_accept_filters);
548
0
#endif
549
550
0
#if defined ZMQ_HAVE_SO_PEERCRED
551
0
        case ZMQ_IPC_FILTER_PID:
552
0
            return do_setsockopt_set (optval_, optvallen_,
553
0
                                      &ipc_pid_accept_filters);
554
0
#endif
555
556
0
        case ZMQ_PLAIN_SERVER:
557
0
            if (is_int && (value == 0 || value == 1)) {
558
0
                as_server = value;
559
0
                mechanism = value ? ZMQ_PLAIN : ZMQ_NULL;
560
0
                return 0;
561
0
            }
562
0
            break;
563
564
0
        case ZMQ_PLAIN_USERNAME:
565
0
            if (optvallen_ == 0 && optval_ == NULL) {
566
0
                mechanism = ZMQ_NULL;
567
0
                return 0;
568
0
            } else if (optvallen_ > 0 && optvallen_ <= UCHAR_MAX
569
0
                       && optval_ != NULL) {
570
0
                plain_username.assign (static_cast<const char *> (optval_),
571
0
                                       optvallen_);
572
0
                as_server = 0;
573
0
                mechanism = ZMQ_PLAIN;
574
0
                return 0;
575
0
            }
576
0
            break;
577
578
0
        case ZMQ_PLAIN_PASSWORD:
579
0
            if (optvallen_ == 0 && optval_ == NULL) {
580
0
                mechanism = ZMQ_NULL;
581
0
                return 0;
582
0
            } else if (optvallen_ > 0 && optvallen_ <= UCHAR_MAX
583
0
                       && optval_ != NULL) {
584
0
                plain_password.assign (static_cast<const char *> (optval_),
585
0
                                       optvallen_);
586
0
                as_server = 0;
587
0
                mechanism = ZMQ_PLAIN;
588
0
                return 0;
589
0
            }
590
0
            break;
591
592
0
        case ZMQ_ZAP_DOMAIN:
593
0
            return do_setsockopt_string_allow_empty_relaxed (
594
0
              optval_, optvallen_, &zap_domain, UCHAR_MAX);
595
596
            //  If curve encryption isn't built, these options provoke EINVAL
597
0
#ifdef ZMQ_HAVE_CURVE
598
0
        case ZMQ_CURVE_SERVER:
599
0
            if (is_int && (value == 0 || value == 1)) {
600
0
                as_server = value;
601
0
                mechanism = value ? ZMQ_CURVE : ZMQ_NULL;
602
0
                return 0;
603
0
            }
604
0
            break;
605
606
0
        case ZMQ_CURVE_PUBLICKEY:
607
0
            if (0 == set_curve_key (curve_public_key, optval_, optvallen_)) {
608
0
                return 0;
609
0
            }
610
0
            break;
611
612
0
        case ZMQ_CURVE_SECRETKEY:
613
0
            if (0 == set_curve_key (curve_secret_key, optval_, optvallen_)) {
614
0
                return 0;
615
0
            }
616
0
            break;
617
618
0
        case ZMQ_CURVE_SERVERKEY:
619
0
            if (0 == set_curve_key (curve_server_key, optval_, optvallen_)) {
620
0
                as_server = 0;
621
0
                return 0;
622
0
            }
623
0
            break;
624
0
#endif
625
626
0
        case ZMQ_CONFLATE:
627
0
            return do_setsockopt_int_as_bool_strict (optval_, optvallen_,
628
0
                                                     &conflate);
629
630
            //  If libgssapi isn't installed, these options provoke EINVAL
631
#ifdef HAVE_LIBGSSAPI_KRB5
632
        case ZMQ_GSSAPI_SERVER:
633
            if (is_int && (value == 0 || value == 1)) {
634
                as_server = value;
635
                mechanism = ZMQ_GSSAPI;
636
                return 0;
637
            }
638
            break;
639
640
        case ZMQ_GSSAPI_PRINCIPAL:
641
            if (optvallen_ > 0 && optvallen_ <= UCHAR_MAX && optval_ != NULL) {
642
                gss_principal.assign ((const char *) optval_, optvallen_);
643
                mechanism = ZMQ_GSSAPI;
644
                return 0;
645
            }
646
            break;
647
648
        case ZMQ_GSSAPI_SERVICE_PRINCIPAL:
649
            if (optvallen_ > 0 && optvallen_ <= UCHAR_MAX && optval_ != NULL) {
650
                gss_service_principal.assign ((const char *) optval_,
651
                                              optvallen_);
652
                mechanism = ZMQ_GSSAPI;
653
                as_server = 0;
654
                return 0;
655
            }
656
            break;
657
658
        case ZMQ_GSSAPI_PLAINTEXT:
659
            return do_setsockopt_int_as_bool_strict (optval_, optvallen_,
660
                                                     &gss_plaintext);
661
662
        case ZMQ_GSSAPI_PRINCIPAL_NAMETYPE:
663
            if (is_int
664
                && (value == ZMQ_GSSAPI_NT_HOSTBASED
665
                    || value == ZMQ_GSSAPI_NT_USER_NAME
666
                    || value == ZMQ_GSSAPI_NT_KRB5_PRINCIPAL)) {
667
                gss_principal_nt = value;
668
                return 0;
669
            }
670
            break;
671
672
        case ZMQ_GSSAPI_SERVICE_PRINCIPAL_NAMETYPE:
673
            if (is_int
674
                && (value == ZMQ_GSSAPI_NT_HOSTBASED
675
                    || value == ZMQ_GSSAPI_NT_USER_NAME
676
                    || value == ZMQ_GSSAPI_NT_KRB5_PRINCIPAL)) {
677
                gss_service_principal_nt = value;
678
                return 0;
679
            }
680
            break;
681
#endif
682
683
0
        case ZMQ_HANDSHAKE_IVL:
684
0
            if (is_int && value >= 0) {
685
0
                handshake_ivl = value;
686
0
                return 0;
687
0
            }
688
0
            break;
689
690
0
        case ZMQ_INVERT_MATCHING:
691
0
            return do_setsockopt_int_as_bool_relaxed (optval_, optvallen_,
692
0
                                                      &invert_matching);
693
694
0
        case ZMQ_HEARTBEAT_IVL:
695
0
            if (is_int && value >= 0) {
696
0
                heartbeat_interval = value;
697
0
                return 0;
698
0
            }
699
0
            break;
700
701
0
        case ZMQ_HEARTBEAT_TTL:
702
            // Convert this to deciseconds from milliseconds
703
0
            value = value / deciseconds_per_millisecond;
704
0
            if (is_int && value >= 0 && value <= UINT16_MAX) {
705
0
                heartbeat_ttl = static_cast<uint16_t> (value);
706
0
                return 0;
707
0
            }
708
0
            break;
709
710
0
        case ZMQ_HEARTBEAT_TIMEOUT:
711
0
            if (is_int && value >= 0) {
712
0
                heartbeat_timeout = value;
713
0
                return 0;
714
0
            }
715
0
            break;
716
717
#ifdef ZMQ_HAVE_VMCI
718
        case ZMQ_VMCI_BUFFER_SIZE:
719
            return do_setsockopt (optval_, optvallen_, &vmci_buffer_size);
720
721
        case ZMQ_VMCI_BUFFER_MIN_SIZE:
722
            return do_setsockopt (optval_, optvallen_, &vmci_buffer_min_size);
723
724
        case ZMQ_VMCI_BUFFER_MAX_SIZE:
725
            return do_setsockopt (optval_, optvallen_, &vmci_buffer_max_size);
726
727
        case ZMQ_VMCI_CONNECT_TIMEOUT:
728
            return do_setsockopt (optval_, optvallen_, &vmci_connect_timeout);
729
#endif
730
731
0
        case ZMQ_USE_FD:
732
0
            if (is_int && value >= -1) {
733
0
                use_fd = value;
734
0
                return 0;
735
0
            }
736
0
            break;
737
738
0
        case ZMQ_BINDTODEVICE:
739
0
            return do_setsockopt_string_allow_empty_strict (
740
0
              optval_, optvallen_, &bound_device, BINDDEVSIZ);
741
742
0
        case ZMQ_ZAP_ENFORCE_DOMAIN:
743
0
            return do_setsockopt_int_as_bool_relaxed (optval_, optvallen_,
744
0
                                                      &zap_enforce_domain);
745
746
0
        case ZMQ_LOOPBACK_FASTPATH:
747
0
            return do_setsockopt_int_as_bool_relaxed (optval_, optvallen_,
748
0
                                                      &loopback_fastpath);
749
750
0
        case ZMQ_METADATA:
751
0
            if (optvallen_ > 0 && !is_int) {
752
0
                const std::string s (static_cast<const char *> (optval_),
753
0
                                     optvallen_);
754
0
                const size_t pos = s.find (':');
755
0
                if (pos != std::string::npos && pos != 0
756
0
                    && pos != s.length () - 1) {
757
0
                    const std::string key = s.substr (0, pos);
758
0
                    if (key.compare (0, 2, "X-") == 0
759
0
                        && key.length () <= UCHAR_MAX) {
760
0
                        std::string val = s.substr (pos + 1, s.length ());
761
0
                        app_metadata.insert (
762
0
                          std::pair<std::string, std::string> (key, val));
763
0
                        return 0;
764
0
                    }
765
0
                }
766
0
            }
767
0
            errno = EINVAL;
768
0
            return -1;
769
770
0
        case ZMQ_MULTICAST_LOOP:
771
0
            return do_setsockopt_int_as_bool_relaxed (optval_, optvallen_,
772
0
                                                      &multicast_loop);
773
774
0
#ifdef ZMQ_BUILD_DRAFT_API
775
0
        case ZMQ_IN_BATCH_SIZE:
776
0
            if (is_int && value > 0) {
777
0
                in_batch_size = value;
778
0
                return 0;
779
0
            }
780
0
            break;
781
782
0
        case ZMQ_OUT_BATCH_SIZE:
783
0
            if (is_int && value > 0) {
784
0
                out_batch_size = value;
785
0
                return 0;
786
0
            }
787
0
            break;
788
789
0
        case ZMQ_BUSY_POLL:
790
0
            if (is_int) {
791
0
                busy_poll = value;
792
0
                return 0;
793
0
            }
794
0
            break;
795
#ifdef ZMQ_HAVE_WSS
796
        case ZMQ_WSS_KEY_PEM:
797
            // TODO: check if valid certificate
798
            wss_key_pem = std::string ((char *) optval_, optvallen_);
799
            return 0;
800
        case ZMQ_WSS_CERT_PEM:
801
            // TODO: check if valid certificate
802
            wss_cert_pem = std::string ((char *) optval_, optvallen_);
803
            return 0;
804
        case ZMQ_WSS_TRUST_PEM:
805
            // TODO: check if valid certificate
806
            wss_trust_pem = std::string ((char *) optval_, optvallen_);
807
            return 0;
808
        case ZMQ_WSS_HOSTNAME:
809
            wss_hostname = std::string ((char *) optval_, optvallen_);
810
            return 0;
811
        case ZMQ_WSS_TRUST_SYSTEM:
812
            return do_setsockopt_int_as_bool_strict (optval_, optvallen_,
813
                                                     &wss_trust_system);
814
#endif
815
816
#ifdef ZMQ_HAVE_NORM
817
        case ZMQ_NORM_MODE:
818
            if (is_int && value >= 0 && value <= 4) {
819
                norm_mode = value;
820
                return 0;
821
            }
822
            break;
823
824
        case ZMQ_NORM_UNICAST_NACK:
825
            return do_setsockopt_int_as_bool_strict (optval_, optvallen_,
826
                                                     &norm_unicast_nacks);
827
828
        case ZMQ_NORM_BUFFER_SIZE:
829
            if (is_int && value > 0) {
830
                norm_buffer_size = value;
831
                return 0;
832
            }
833
            break;
834
835
        case ZMQ_NORM_SEGMENT_SIZE:
836
            if (is_int && value > 0) {
837
                norm_segment_size = value;
838
                return 0;
839
            }
840
            break;
841
842
        case ZMQ_NORM_BLOCK_SIZE:
843
            if (is_int && value > 0 && value <= 255) {
844
                norm_block_size = value;
845
                return 0;
846
            }
847
            break;
848
849
        case ZMQ_NORM_NUM_PARITY:
850
            if (is_int && value >= 0 && value < 255) {
851
                norm_num_parity = value;
852
                return 0;
853
            }
854
            break;
855
856
        case ZMQ_NORM_NUM_AUTOPARITY:
857
            if (is_int && value >= 0 && value < 255) {
858
                norm_num_autoparity = value;
859
                return 0;
860
            }
861
            break;
862
863
        case ZMQ_NORM_PUSH:
864
            return do_setsockopt_int_as_bool_strict (optval_, optvallen_,
865
                                                     &norm_push_enable);
866
#endif //ZMQ_HAVE_NORM
867
868
0
        case ZMQ_HELLO_MSG:
869
0
            if (optvallen_ > 0) {
870
0
                unsigned char *bytes = (unsigned char *) optval_;
871
0
                hello_msg =
872
0
                  std::vector<unsigned char> (bytes, bytes + optvallen_);
873
0
            } else {
874
0
                hello_msg = std::vector<unsigned char> ();
875
0
            }
876
877
0
            return 0;
878
879
0
        case ZMQ_DISCONNECT_MSG:
880
0
            if (optvallen_ > 0) {
881
0
                unsigned char *bytes = (unsigned char *) optval_;
882
0
                disconnect_msg =
883
0
                  std::vector<unsigned char> (bytes, bytes + optvallen_);
884
0
            } else {
885
0
                disconnect_msg = std::vector<unsigned char> ();
886
0
            }
887
888
0
            return 0;
889
890
0
        case ZMQ_PRIORITY:
891
0
            if (is_int && value >= 0) {
892
0
                priority = value;
893
0
                return 0;
894
0
            }
895
0
            break;
896
897
0
        case ZMQ_HICCUP_MSG:
898
0
            if (optvallen_ > 0) {
899
0
                unsigned char *bytes = (unsigned char *) optval_;
900
0
                hiccup_msg =
901
0
                  std::vector<unsigned char> (bytes, bytes + optvallen_);
902
0
            } else {
903
0
                hiccup_msg = std::vector<unsigned char> ();
904
0
            }
905
906
0
            return 0;
907
908
909
0
#endif
910
911
0
        default:
912
#if defined(ZMQ_ACT_MILITANT)
913
            //  There are valid scenarios for probing with unknown socket option
914
            //  values, e.g. to check if security is enabled or not. This will not
915
            //  provoke a militant assert. However, passing bad values to a valid
916
            //  socket option will, if ZMQ_ACT_MILITANT is defined.
917
            malformed = false;
918
#endif
919
0
            break;
920
0
    }
921
922
        // TODO mechanism should either be set explicitly, or determined when
923
        // connecting. currently, it depends on the order of setsockopt calls
924
        // if there is some inconsistency, which is confusing. in addition,
925
        // the assumed or set mechanism should be queryable (as a socket option)
926
927
#if defined(ZMQ_ACT_MILITANT)
928
    //  There is no valid use case for passing an error back to the application
929
    //  when it sent malformed arguments to a socket option. Use ./configure
930
    //  --with-militant to enable this checking.
931
    if (malformed)
932
        zmq_assert (false);
933
#endif
934
0
    errno = EINVAL;
935
0
    return -1;
936
0
}
937
938
int zmq::options_t::getsockopt (int option_,
939
                                void *optval_,
940
                                size_t *optvallen_) const
941
0
{
942
0
    const bool is_int = (*optvallen_ == sizeof (int));
943
0
    int *value = static_cast<int *> (optval_);
944
#if defined(ZMQ_ACT_MILITANT)
945
    bool malformed = true; //  Did caller pass a bad option value?
946
#endif
947
948
0
    switch (option_) {
949
0
        case ZMQ_SNDHWM:
950
0
            if (is_int) {
951
0
                *value = sndhwm;
952
0
                return 0;
953
0
            }
954
0
            break;
955
956
0
        case ZMQ_RCVHWM:
957
0
            if (is_int) {
958
0
                *value = rcvhwm;
959
0
                return 0;
960
0
            }
961
0
            break;
962
963
0
        case ZMQ_AFFINITY:
964
0
            if (*optvallen_ == sizeof (uint64_t)) {
965
0
                *(static_cast<uint64_t *> (optval_)) = affinity;
966
0
                return 0;
967
0
            }
968
0
            break;
969
970
0
        case ZMQ_ROUTING_ID:
971
0
            return do_getsockopt (optval_, optvallen_, routing_id,
972
0
                                  routing_id_size);
973
974
0
        case ZMQ_RATE:
975
0
            if (is_int) {
976
0
                *value = rate;
977
0
                return 0;
978
0
            }
979
0
            break;
980
981
0
        case ZMQ_RECOVERY_IVL:
982
0
            if (is_int) {
983
0
                *value = recovery_ivl;
984
0
                return 0;
985
0
            }
986
0
            break;
987
988
0
        case ZMQ_SNDBUF:
989
0
            if (is_int) {
990
0
                *value = sndbuf;
991
0
                return 0;
992
0
            }
993
0
            break;
994
995
0
        case ZMQ_RCVBUF:
996
0
            if (is_int) {
997
0
                *value = rcvbuf;
998
0
                return 0;
999
0
            }
1000
0
            break;
1001
1002
0
        case ZMQ_TOS:
1003
0
            if (is_int) {
1004
0
                *value = tos;
1005
0
                return 0;
1006
0
            }
1007
0
            break;
1008
1009
0
        case ZMQ_TYPE:
1010
0
            if (is_int) {
1011
0
                *value = type;
1012
0
                return 0;
1013
0
            }
1014
0
            break;
1015
1016
0
        case ZMQ_LINGER:
1017
0
            if (is_int) {
1018
0
                *value = linger.load ();
1019
0
                return 0;
1020
0
            }
1021
0
            break;
1022
1023
0
        case ZMQ_CONNECT_TIMEOUT:
1024
0
            if (is_int) {
1025
0
                *value = connect_timeout;
1026
0
                return 0;
1027
0
            }
1028
0
            break;
1029
1030
0
        case ZMQ_TCP_MAXRT:
1031
0
            if (is_int) {
1032
0
                *value = tcp_maxrt;
1033
0
                return 0;
1034
0
            }
1035
0
            break;
1036
1037
0
        case ZMQ_RECONNECT_STOP:
1038
0
            if (is_int) {
1039
0
                *value = reconnect_stop;
1040
0
                return 0;
1041
0
            }
1042
0
            break;
1043
1044
0
        case ZMQ_RECONNECT_IVL:
1045
0
            if (is_int) {
1046
0
                *value = reconnect_ivl;
1047
0
                return 0;
1048
0
            }
1049
0
            break;
1050
1051
0
        case ZMQ_RECONNECT_IVL_MAX:
1052
0
            if (is_int) {
1053
0
                *value = reconnect_ivl_max;
1054
0
                return 0;
1055
0
            }
1056
0
            break;
1057
1058
0
        case ZMQ_BACKLOG:
1059
0
            if (is_int) {
1060
0
                *value = backlog;
1061
0
                return 0;
1062
0
            }
1063
0
            break;
1064
1065
0
        case ZMQ_MAXMSGSIZE:
1066
0
            if (*optvallen_ == sizeof (int64_t)) {
1067
0
                *(static_cast<int64_t *> (optval_)) = maxmsgsize;
1068
0
                *optvallen_ = sizeof (int64_t);
1069
0
                return 0;
1070
0
            }
1071
0
            break;
1072
1073
0
        case ZMQ_MULTICAST_HOPS:
1074
0
            if (is_int) {
1075
0
                *value = multicast_hops;
1076
0
                return 0;
1077
0
            }
1078
0
            break;
1079
1080
0
        case ZMQ_MULTICAST_MAXTPDU:
1081
0
            if (is_int) {
1082
0
                *value = multicast_maxtpdu;
1083
0
                return 0;
1084
0
            }
1085
0
            break;
1086
1087
0
        case ZMQ_RCVTIMEO:
1088
0
            if (is_int) {
1089
0
                *value = rcvtimeo;
1090
0
                return 0;
1091
0
            }
1092
0
            break;
1093
1094
0
        case ZMQ_SNDTIMEO:
1095
0
            if (is_int) {
1096
0
                *value = sndtimeo;
1097
0
                return 0;
1098
0
            }
1099
0
            break;
1100
1101
0
        case ZMQ_IPV4ONLY:
1102
0
            if (is_int) {
1103
0
                *value = 1 - ipv6;
1104
0
                return 0;
1105
0
            }
1106
0
            break;
1107
1108
0
        case ZMQ_IPV6:
1109
0
            if (is_int) {
1110
0
                *value = ipv6;
1111
0
                return 0;
1112
0
            }
1113
0
            break;
1114
1115
0
        case ZMQ_IMMEDIATE:
1116
0
            if (is_int) {
1117
0
                *value = immediate;
1118
0
                return 0;
1119
0
            }
1120
0
            break;
1121
1122
0
        case ZMQ_SOCKS_PROXY:
1123
0
            return do_getsockopt (optval_, optvallen_, socks_proxy_address);
1124
1125
0
        case ZMQ_SOCKS_USERNAME:
1126
0
            return do_getsockopt (optval_, optvallen_, socks_proxy_username);
1127
1128
0
        case ZMQ_SOCKS_PASSWORD:
1129
0
            return do_getsockopt (optval_, optvallen_, socks_proxy_password);
1130
1131
0
        case ZMQ_TCP_KEEPALIVE:
1132
0
            if (is_int) {
1133
0
                *value = tcp_keepalive;
1134
0
                return 0;
1135
0
            }
1136
0
            break;
1137
1138
0
        case ZMQ_TCP_KEEPALIVE_CNT:
1139
0
            if (is_int) {
1140
0
                *value = tcp_keepalive_cnt;
1141
0
                return 0;
1142
0
            }
1143
0
            break;
1144
1145
0
        case ZMQ_TCP_KEEPALIVE_IDLE:
1146
0
            if (is_int) {
1147
0
                *value = tcp_keepalive_idle;
1148
0
                return 0;
1149
0
            }
1150
0
            break;
1151
1152
0
        case ZMQ_TCP_KEEPALIVE_INTVL:
1153
0
            if (is_int) {
1154
0
                *value = tcp_keepalive_intvl;
1155
0
                return 0;
1156
0
            }
1157
0
            break;
1158
1159
0
        case ZMQ_MECHANISM:
1160
0
            if (is_int) {
1161
0
                *value = mechanism;
1162
0
                return 0;
1163
0
            }
1164
0
            break;
1165
1166
0
        case ZMQ_PLAIN_SERVER:
1167
0
            if (is_int) {
1168
0
                *value = as_server && mechanism == ZMQ_PLAIN;
1169
0
                return 0;
1170
0
            }
1171
0
            break;
1172
1173
0
        case ZMQ_PLAIN_USERNAME:
1174
0
            return do_getsockopt (optval_, optvallen_, plain_username);
1175
1176
0
        case ZMQ_PLAIN_PASSWORD:
1177
0
            return do_getsockopt (optval_, optvallen_, plain_password);
1178
1179
0
        case ZMQ_ZAP_DOMAIN:
1180
0
            return do_getsockopt (optval_, optvallen_, zap_domain);
1181
1182
            //  If curve encryption isn't built, these options provoke EINVAL
1183
0
#ifdef ZMQ_HAVE_CURVE
1184
0
        case ZMQ_CURVE_SERVER:
1185
0
            if (is_int) {
1186
0
                *value = as_server && mechanism == ZMQ_CURVE;
1187
0
                return 0;
1188
0
            }
1189
0
            break;
1190
1191
0
        case ZMQ_CURVE_PUBLICKEY:
1192
0
            return do_getsockopt_curve_key (optval_, optvallen_,
1193
0
                                            curve_public_key);
1194
1195
0
        case ZMQ_CURVE_SECRETKEY:
1196
0
            return do_getsockopt_curve_key (optval_, optvallen_,
1197
0
                                            curve_secret_key);
1198
1199
0
        case ZMQ_CURVE_SERVERKEY:
1200
0
            return do_getsockopt_curve_key (optval_, optvallen_,
1201
0
                                            curve_server_key);
1202
0
#endif
1203
1204
0
        case ZMQ_CONFLATE:
1205
0
            if (is_int) {
1206
0
                *value = conflate;
1207
0
                return 0;
1208
0
            }
1209
0
            break;
1210
1211
            //  If libgssapi isn't installed, these options provoke EINVAL
1212
#ifdef HAVE_LIBGSSAPI_KRB5
1213
        case ZMQ_GSSAPI_SERVER:
1214
            if (is_int) {
1215
                *value = as_server && mechanism == ZMQ_GSSAPI;
1216
                return 0;
1217
            }
1218
            break;
1219
1220
        case ZMQ_GSSAPI_PRINCIPAL:
1221
            return do_getsockopt (optval_, optvallen_, gss_principal);
1222
1223
        case ZMQ_GSSAPI_SERVICE_PRINCIPAL:
1224
            return do_getsockopt (optval_, optvallen_, gss_service_principal);
1225
1226
        case ZMQ_GSSAPI_PLAINTEXT:
1227
            if (is_int) {
1228
                *value = gss_plaintext;
1229
                return 0;
1230
            }
1231
            break;
1232
1233
        case ZMQ_GSSAPI_PRINCIPAL_NAMETYPE:
1234
            if (is_int) {
1235
                *value = gss_principal_nt;
1236
                return 0;
1237
            }
1238
            break;
1239
        case ZMQ_GSSAPI_SERVICE_PRINCIPAL_NAMETYPE:
1240
            if (is_int) {
1241
                *value = gss_service_principal_nt;
1242
                return 0;
1243
            }
1244
            break;
1245
#endif
1246
1247
0
        case ZMQ_HANDSHAKE_IVL:
1248
0
            if (is_int) {
1249
0
                *value = handshake_ivl;
1250
0
                return 0;
1251
0
            }
1252
0
            break;
1253
1254
0
        case ZMQ_INVERT_MATCHING:
1255
0
            if (is_int) {
1256
0
                *value = invert_matching;
1257
0
                return 0;
1258
0
            }
1259
0
            break;
1260
1261
0
        case ZMQ_HEARTBEAT_IVL:
1262
0
            if (is_int) {
1263
0
                *value = heartbeat_interval;
1264
0
                return 0;
1265
0
            }
1266
0
            break;
1267
1268
0
        case ZMQ_HEARTBEAT_TTL:
1269
0
            if (is_int) {
1270
                // Convert the internal deciseconds value to milliseconds
1271
0
                *value = heartbeat_ttl * 100;
1272
0
                return 0;
1273
0
            }
1274
0
            break;
1275
1276
0
        case ZMQ_HEARTBEAT_TIMEOUT:
1277
0
            if (is_int) {
1278
0
                *value = heartbeat_timeout;
1279
0
                return 0;
1280
0
            }
1281
0
            break;
1282
1283
0
        case ZMQ_USE_FD:
1284
0
            if (is_int) {
1285
0
                *value = use_fd;
1286
0
                return 0;
1287
0
            }
1288
0
            break;
1289
1290
0
        case ZMQ_BINDTODEVICE:
1291
0
            return do_getsockopt (optval_, optvallen_, bound_device);
1292
1293
0
        case ZMQ_ZAP_ENFORCE_DOMAIN:
1294
0
            if (is_int) {
1295
0
                *value = zap_enforce_domain;
1296
0
                return 0;
1297
0
            }
1298
0
            break;
1299
1300
0
        case ZMQ_LOOPBACK_FASTPATH:
1301
0
            if (is_int) {
1302
0
                *value = loopback_fastpath;
1303
0
                return 0;
1304
0
            }
1305
0
            break;
1306
1307
0
        case ZMQ_MULTICAST_LOOP:
1308
0
            if (is_int) {
1309
0
                *value = multicast_loop;
1310
0
                return 0;
1311
0
            }
1312
0
            break;
1313
1314
0
#ifdef ZMQ_BUILD_DRAFT_API
1315
0
        case ZMQ_ROUTER_NOTIFY:
1316
0
            if (is_int) {
1317
0
                *value = router_notify;
1318
0
                return 0;
1319
0
            }
1320
0
            break;
1321
1322
0
        case ZMQ_IN_BATCH_SIZE:
1323
0
            if (is_int) {
1324
0
                *value = in_batch_size;
1325
0
                return 0;
1326
0
            }
1327
0
            break;
1328
1329
0
        case ZMQ_OUT_BATCH_SIZE:
1330
0
            if (is_int) {
1331
0
                *value = out_batch_size;
1332
0
                return 0;
1333
0
            }
1334
0
            break;
1335
1336
0
        case ZMQ_PRIORITY:
1337
0
            if (is_int) {
1338
0
                *value = priority;
1339
0
                return 0;
1340
0
            }
1341
0
            break;
1342
1343
0
        case ZMQ_BUSY_POLL:
1344
0
            if (is_int) {
1345
0
                *value = busy_poll;
1346
0
            }
1347
0
            break;
1348
1349
#ifdef ZMQ_HAVE_NORM
1350
        case ZMQ_NORM_MODE:
1351
            if (is_int) {
1352
                *value = norm_mode;
1353
                return 0;
1354
            }
1355
            break;
1356
1357
        case ZMQ_NORM_UNICAST_NACK:
1358
            if (is_int) {
1359
                *value = norm_unicast_nacks;
1360
                return 0;
1361
            }
1362
            break;
1363
1364
        case ZMQ_NORM_BUFFER_SIZE:
1365
            if (is_int) {
1366
                *value = norm_buffer_size;
1367
                return 0;
1368
            }
1369
            break;
1370
1371
        case ZMQ_NORM_SEGMENT_SIZE:
1372
            if (is_int) {
1373
                *value = norm_segment_size;
1374
                return 0;
1375
            }
1376
            break;
1377
1378
        case ZMQ_NORM_BLOCK_SIZE:
1379
            if (is_int) {
1380
                *value = norm_block_size;
1381
                return 0;
1382
            }
1383
            break;
1384
1385
        case ZMQ_NORM_NUM_PARITY:
1386
            if (is_int) {
1387
                *value = norm_num_parity;
1388
                return 0;
1389
            }
1390
            break;
1391
1392
        case ZMQ_NORM_NUM_AUTOPARITY:
1393
            if (is_int) {
1394
                *value = norm_num_autoparity;
1395
                return 0;
1396
            }
1397
            break;
1398
1399
        case ZMQ_NORM_PUSH:
1400
            if (is_int) {
1401
                *value = norm_push_enable;
1402
                return 0;
1403
            }
1404
            break;
1405
#endif //ZMQ_HAVE_NORM
1406
1407
0
#endif
1408
1409
1410
0
        default:
1411
#if defined(ZMQ_ACT_MILITANT)
1412
            malformed = false;
1413
#endif
1414
0
            break;
1415
0
    }
1416
#if defined(ZMQ_ACT_MILITANT)
1417
    if (malformed)
1418
        zmq_assert (false);
1419
#endif
1420
0
    errno = EINVAL;
1421
0
    return -1;
1422
0
}