1 // Copyright (C) 2016-2020 John Donoghue <john.donoghue@ieee.org> 2 // 3 // This program is free software; you can redistribute it and/or modify it under 4 // the terms of the GNU General Public License as published by the Free Software 5 // Foundation; either version 3 of the License, or (at your option) any later 6 // version. 7 // 8 // This program is distributed in the hope that it will be useful, but WITHOUT 9 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 11 // details. 12 // 13 // You should have received a copy of the GNU General Public License along with 14 // this program; if not, see <http://www.gnu.org/licenses/>. 15 16 // Octave Includes 17 #include <octave/oct.h> 18 #include <octave/defun-dld.h> 19 20 #ifdef HAVE_CONFIG_H 21 # include "config.h" 22 #endif 23 24 #include "socket_class.h" 25 26 #include <zmq.h> 27 28 // PKG_ADD: autoload ("zmq_getsockopt", "zeromq.oct"); 29 DEFUN_DLD (zmq_getsockopt, args, nargout, 30 "-*- texinfo -*-\n\ 31 @deftypefn {Loadable Function} @var{value} = zmq_getsockopt (@var{sock}, @var{optionid})\n \ 32 \n\ 33 Get the current value of an option.\n \ 34 \n \ 35 @var{sock} - the socket to connect.\n \ 36 \n \ 37 @var{optionid} - the setsockopt option to set.\n \ 38 \n \ 39 @var{value} - the value set for the option, or [].\n \ 40 \n \ 41 Valid @var{optionid}s are:\n \ 42 @table @asis\n \ 43 @item @code{ZMQ_RCVMORE}\n \ 44 Flag for whether a message has been split into multiple messages. The return value will be either 0 or 1.\n \ 45 @item @code{ZMQ_TYPE}\n \ 46 Socket type for zeromq socket created with zmq_socket.\n \ 47 Valid types are the same as the socket type value specified with zmq_socket. \n \ 48 @item @code{ZMQ_EVENTS}\n \ 49 Get the event state of zeromq socket.\n \ 50 The returned value is a bit mask that may contain the following set values:\n \ 51 @itemize\n \ 52 @item @code{ZMQ_POLLIN} set when at least one message is available to read and zmq_recv will not block.\n \ 53 @item @code{ZMQ_POLLOUT} set when at least one message can be written without zmq_send blocking.\n \ 54 @end itemize\n \ 55 @item @code{ZMQ_IDENTITY}\n \ 56 Get the socket identity value\n \ 57 @item @code{ZMQ_LAST_ENDPOINT}\n \ 58 Get the last endpoint the socket was connected to\n \ 59 @item @code{ZMQ_CONNECT_TIMEOUT}\n \ 60 Get the connect timeout value\n \ 61 @item @code{ZMQ_SOCKS_PROXY}\n \ 62 Get the SOCKS5 proxy value (string)\n \ 63 @item @code{ZMQ_CURVE_SERVER}\n \ 64 Get whether socket is a curve server (1) or not (0)\n \ 65 @item @code{ZMQ_CURVE_PRIVATEKEY}\n \ 66 Get a the curve socket private key (string)\n \ 67 @item @code{ZMQ_CURVE_PUBLICKEY}\n \ 68 Get a the curve socket public key (string)\n \ 69 @item @code{ZMQ_CURVE_SERVERKEY}\n \ 70 Get a the curve socket public key (string)\n \ 71 @item @code{ZMQ_PLAIN_SERVER}\n \ 72 Get whether socket server will use plain authentication (1) or not (0)\n \ 73 @item @code{ZMQ_PLAIN_USERNAME}\n \ 74 Get the plain socket username (string)\n \ 75 @item @code{ZMQ_PLAIN_PASSWORD}\n \ 76 Get the plain socket password (string)\n \ 77 @item @code{ZMQ_GSSAPI_SERVER}\n \ 78 Get whether socket server will use gssapi authentication (1) or not (0)\n \ 79 @item @code{ZMQ_GSSAPI_PLAINTEXT}\n \ 80 Get whether socket will encrypt gssapi authentication (1) or not (0)\n \ 81 @item @code{ZMQ_GSSAPI_PRINCIPAL}\n \ 82 Get the name of the gssapi principal (string)\n \ 83 @item @code{ZMQ_GSSAPI_SERVICE_PRINCIPAL}\n \ 84 Get the name of the gssapi service principal (string)\n \ 85 @item @code{ZMQ_MECHANISM}\n \ 86 Get the security mechanism (ZMQ_NULL, ZMQ_PLAIN, ZMQ_CURVE, ZMQ_GSSAPI)\n \ 87 @end table\n \ 88 \n \ 89 @seealso{zmq_socket, zmq_setsockopt}\n \ 90 @end deftypefn") 91 { 92 init_types (); 93 94 95 if (args.length () != 2 || 96 args(0).type_id () != octave_zeromq_socket::static_type_id ()) 97 { 98 print_usage (); 99 return octave_value (); 100 } 101 102 if (args (1).OV_ISINTEGER () && !args (1).OV_ISFLOAT ()) 103 { 104 print_usage (); 105 return octave_value (); 106 } 107 108 octave_zeromq_socket * sock = NULL; 109 110 const octave_base_value& rep = args (0).get_rep (); 111 112 sock = &((octave_zeromq_socket &)rep); 113 114 int opt = args (1).int_value (); 115 116 std::string strvalue; 117 118 octave_value ret; 119 switch(opt) 120 { 121 case ZMQ_RCVMORE: 122 { 123 #if ZMQ_VERSION < ZMQ_MAKE_VERSION(3,0,0) 124 int64_t flag = 0; 125 #else 126 int flag = 0; 127 #endif 128 size_t sz = sizeof (flag); 129 if (! sock->getsockopt (opt, &flag, &sz)) 130 error ("zeromq: failed getsockopt"); 131 132 ret = octave_value (flag); 133 } 134 break; 135 #if ZMQ_VERSION < ZMQ_MAKE_VERSION(3,0,0) 136 case ZMQ_HWM: 137 { 138 uint64_t value = 0; 139 size_t sz = sizeof (value); 140 if (! sock->getsockopt (opt, &value, &sz)) 141 error ("zeromq: failed getsockopt"); 142 143 ret = octave_value (value); 144 } 145 break; 146 #endif 147 #if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3,0,0) 148 case ZMQ_SNDHWM: 149 { 150 int value = 0; 151 size_t sz = sizeof (value); 152 if ( !sock->getsockopt (opt, &value, &sz)) 153 error ("zeromq: failed getsockopt"); 154 155 ret = octave_value (value); 156 } 157 break; 158 #endif 159 #if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3,0,0) 160 case ZMQ_RCVHWM: 161 { 162 int value = 0; 163 size_t sz = sizeof (value); 164 if (! sock->getsockopt (opt, &value, &sz)) 165 error ("zeromq: failed getsockopt"); 166 167 ret = octave_value (value); 168 } 169 break; 170 #endif 171 #if ZMQ_VERSION >= ZMQ_MAKE_VERSION(2,1,0) 172 case ZMQ_TYPE: 173 { 174 ret = octave_value (sock->socktype ()); 175 } 176 break; 177 #endif 178 case ZMQ_EVENTS: 179 { 180 #if ZMQ_VERSION < ZMQ_MAKE_VERSION(3,0,0) 181 uint32_t value = 0; 182 #else 183 int value = 0; 184 #endif 185 size_t sz = sizeof (value); 186 if (! sock->getsockopt (opt, &value, &sz)) 187 error ("zeromq: ZMQ_EVENTS failed getsockopt"); 188 189 ret = octave_value (value); 190 } 191 break; 192 case ZMQ_IDENTITY: 193 { 194 uint8_t value[256]; 195 size_t sz = sizeof (value); 196 197 if (! sock->getsockopt (opt, value, &sz)) 198 error ("zeromq: failed getsockopt"); 199 200 if (sz > 0) 201 { 202 uint8NDArray data( dim_vector (1,sz) ); 203 for (size_t i=0;i<sz;i++) 204 { 205 data(i) = value[i]; 206 } 207 208 ret = data; 209 } 210 else 211 ret = uint8NDArray (dim_vector (1,0)); 212 } 213 break; 214 215 #if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3,2,0) 216 case ZMQ_LAST_ENDPOINT: 217 { 218 char value[1024]; 219 size_t sz = sizeof (value); 220 221 if (! sock->getsockopt (opt, value, &sz)) 222 error ("zeromq: failed getsockopt"); 223 224 if (sz > 0) 225 { 226 strvalue = std::string(value, sz-1); 227 } 228 else 229 strvalue = ""; 230 231 ret = octave_value(strvalue); 232 } 233 break; 234 #endif 235 #if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4,2,0) 236 case ZMQ_CONNECT_TIMEOUT: 237 { 238 int value; 239 size_t sz = sizeof (value); 240 241 if (! sock->getsockopt (opt, &value, &sz)) 242 error ("zeromq: failed getsockopt"); 243 244 ret = octave_value (value); 245 } 246 break; 247 #endif 248 #ifdef ZMQ_SOCKS_PROXY 249 case ZMQ_SOCKS_PROXY: 250 { 251 char value[1024]; 252 size_t sz = sizeof(value); 253 254 if (! sock->getsockopt (opt, value, &sz)) 255 error ("zeromq: failed getsockopt"); 256 257 if (sz > 0) 258 { 259 strvalue = std::string(value, sz-1); 260 } 261 else 262 strvalue = ""; 263 264 ret = octave_value(strvalue); 265 } 266 break; 267 #endif 268 #ifdef ZMQ_CURVE_SERVER 269 case ZMQ_CURVE_SERVER: 270 { 271 int value; 272 size_t sz = sizeof (value); 273 274 if (! sock->getsockopt (opt, &value, &sz)) 275 error ("zeromq: failed getsockopt"); 276 277 ret = octave_value (value); 278 } 279 break; 280 #endif 281 282 #ifdef ZMQ_CURVE_PUBLICKEY 283 case ZMQ_CURVE_PUBLICKEY: 284 { 285 char value[1024]; 286 size_t sz = 41; 287 288 if (! sock->getsockopt (opt, value, &sz)) 289 error ("zeromq: failed getsockopt"); 290 291 if (sz > 0) 292 { 293 strvalue = std::string(value, sz-1); 294 } 295 else 296 strvalue = ""; 297 298 ret = octave_value(strvalue); 299 } 300 break; 301 #endif 302 #ifdef ZMQ_CURVE_SERVERKEY 303 case ZMQ_CURVE_SERVERKEY: 304 { 305 char value[1024]; 306 size_t sz = 41; 307 308 if (! sock->getsockopt (opt, value, &sz)) 309 error ("zeromq: failed getsockopt"); 310 311 if (sz > 0) 312 { 313 strvalue = std::string(value, sz-1); 314 } 315 else 316 strvalue = ""; 317 318 ret = octave_value(strvalue); 319 } 320 break; 321 #endif 322 #ifdef ZMQ_CURVE_SECRETKEY 323 case ZMQ_CURVE_SECRETKEY: 324 { 325 char value[1024]; 326 size_t sz = 41; 327 328 if (! sock->getsockopt (opt, value, &sz)) 329 error ("zeromq: failed getsockopt"); 330 331 if (sz > 0) 332 { 333 strvalue = std::string(value, sz-1); 334 } 335 else 336 strvalue = ""; 337 338 ret = octave_value(strvalue); 339 } 340 break; 341 #endif 342 #ifdef ZMQ_PLAIN_SERVER 343 case ZMQ_PLAIN_SERVER: 344 { 345 int value; 346 size_t sz = sizeof (value); 347 348 if (! sock->getsockopt (opt, &value, &sz)) 349 error ("zeromq: failed getsockopt"); 350 351 ret = octave_value (value); 352 } 353 break; 354 #endif 355 356 #ifdef ZMQ_PLAIN_USERNAME 357 case ZMQ_PLAIN_USERNAME: 358 { 359 char value[1024]; 360 size_t sz = sizeof (value); 361 362 if (! sock->getsockopt (opt, value, &sz)) 363 error ("zeromq: failed getsockopt"); 364 365 if (sz > 0) 366 { 367 strvalue = std::string(value, sz-1); 368 } 369 else 370 strvalue = ""; 371 372 ret = octave_value(strvalue); 373 } 374 break; 375 #endif 376 #ifdef ZMQ_PLAIN_PASSWORD 377 case ZMQ_PLAIN_PASSWORD: 378 { 379 char value[1024]; 380 size_t sz = sizeof (value); 381 382 if (! sock->getsockopt (opt, value, &sz)) 383 error ("zeromq: failed getsockopt"); 384 385 if (sz > 0) 386 { 387 strvalue = std::string(value, sz-1); 388 } 389 else 390 strvalue = ""; 391 392 ret = octave_value(strvalue); 393 } 394 break; 395 #endif 396 #ifdef ZMQ_GSSAPI_SERVER 397 case ZMQ_GSSAPI_SERVER: 398 { 399 int value; 400 size_t sz = sizeof (value); 401 402 if (! sock->getsockopt (opt, &value, &sz)) 403 error ("zeromq: failed getsockopt"); 404 405 ret = octave_value (value); 406 } 407 break; 408 #endif 409 410 #ifdef ZMQ_GSSAPI_PLAINTEXT 411 case ZMQ_GSSAPI_PLAINTEXT: 412 { 413 int value; 414 size_t sz = sizeof (value); 415 416 if (! sock->getsockopt (opt, &value, &sz)) 417 error ("zeromq: failed getsockopt"); 418 419 ret = octave_value (value); 420 } 421 break; 422 #endif 423 #ifdef ZMQ_GSSAPI_PRINCIPAL 424 case ZMQ_GSSAPI_PRINCIPAL: 425 { 426 char value[1024]; 427 size_t sz = sizeof (value); 428 429 if (! sock->getsockopt (opt, value, &sz)) 430 error ("zeromq: failed getsockopt"); 431 432 if (sz > 0) 433 { 434 strvalue = std::string(value, sz-1); 435 } 436 else 437 strvalue = ""; 438 439 ret = octave_value(strvalue); 440 } 441 break; 442 #endif 443 444 #ifdef ZMQ_GSSAPI_SERVICE_PRINCIPAL 445 case ZMQ_GSSAPI_SERVICE_PRINCIPAL: 446 { 447 char value[1024]; 448 size_t sz = sizeof (value); 449 450 if (! sock->getsockopt (opt, value, &sz)) 451 error ("zeromq: failed getsockopt"); 452 453 if (sz > 0) 454 { 455 strvalue = std::string(value, sz-1); 456 } 457 else 458 strvalue = ""; 459 460 ret = octave_value(strvalue); 461 } 462 break; 463 #endif 464 465 #ifdef ZMQ_MECHANISM 466 case ZMQ_MECHANISM: 467 { 468 int value; 469 size_t sz = sizeof (value); 470 471 if (! sock->getsockopt (opt, &value, &sz)) 472 error ("zeromq: failed getsockopt"); 473 474 ret = octave_value (value); 475 } 476 break; 477 #endif 478 479 default: 480 error ("zeromq: invalid getsockopt value %d", opt); 481 break; 482 } 483 484 return ret; 485 } 486 487 #if 0 488 %!error <Invalid call to zmq_getsockopt> zmq_getsockopt 489 %!error <Invalid call to zmq_getsockopt> zmq_getsockopt(10) 490 491 %!test 492 %! s = zmq_socket(ZMQ_SUB); 493 %! assert(zmq_getsockopt(s, ZMQ_TYPE), ZMQ_SUB); 494 %! zmq_setsockopt(s, ZMQ_IDENTITY, uint8([104 101 108 108 111])); 495 %! assert(zmq_getsockopt(s, ZMQ_IDENTITY), uint8([104 101 108 108 111])); 496 %! zmq_close(s); 497 498 #endif 499