1 //
2 // Copyright 2020 Staysail Systems, Inc. <info@staysail.tech>
3 // Copyright 2018 Capitar IT Group BV <info@capitar.com>
4 //
5 // This software is supplied under the terms of the MIT License, a
6 // copy of which should be located in the distribution where this
7 // file was obtained (LICENSE.txt). A copy of the license may also be
8 // found online at https://opensource.org/licenses/MIT.
9 //
10
11 #include "nng/nng.h"
12 #include "core/nng_impl.h"
13
14 // This file provides the "public" API. This is a thin wrapper around
15 // internal API functions. We use the public prefix instead of internal,
16 // to indicate that these interfaces are intended for applications to use
17 // directly.
18 //
19 // Anything not defined in this file, applications have no business using.
20 // Pretty much every function calls the nni_platform_init to check against
21 // fork related activity.
22
23 #include <stdio.h>
24 #include <string.h>
25
26 void
nng_fini(void)27 nng_fini(void)
28 {
29 nni_sock_closeall();
30 nni_fini();
31 }
32
33 int
nng_close(nng_socket s)34 nng_close(nng_socket s)
35 {
36 int rv;
37 nni_sock *sock;
38
39 // Close is special, because we still want to be able to get
40 // a hold on the socket even if shutdown was called.
41 if ((rv = nni_sock_find(&sock, s.id)) != 0) {
42 return (rv);
43 }
44 // No release -- close releases it.
45 nni_sock_close(sock);
46 return (0);
47 }
48
49 int
nng_socket_id(nng_socket s)50 nng_socket_id(nng_socket s)
51 {
52 return (((int) s.id > 0) ? (int) s.id : -1);
53 }
54
55 void *
nng_alloc(size_t sz)56 nng_alloc(size_t sz)
57 {
58 return (nni_alloc(sz));
59 }
60
61 void
nng_free(void * buf,size_t sz)62 nng_free(void *buf, size_t sz)
63 {
64 nni_free(buf, sz);
65 }
66
67 char *
nng_strdup(const char * src)68 nng_strdup(const char *src)
69 {
70 return (nni_strdup(src));
71 }
72
73 void
nng_strfree(char * s)74 nng_strfree(char *s)
75 {
76 nni_strfree(s);
77 }
78
79 int
nng_recv(nng_socket s,void * buf,size_t * szp,int flags)80 nng_recv(nng_socket s, void *buf, size_t *szp, int flags)
81 {
82 nng_msg *msg;
83 int rv;
84
85 // Note that while it would be nice to make this a zero copy operation,
86 // its not normally possible if a size was specified.
87 if ((rv = nng_recvmsg(s, &msg, flags & ~(NNG_FLAG_ALLOC))) != 0) {
88 return (rv);
89 }
90 if (!(flags & NNG_FLAG_ALLOC)) {
91 memcpy(buf, nng_msg_body(msg),
92 *szp > nng_msg_len(msg) ? nng_msg_len(msg) : *szp);
93 *szp = nng_msg_len(msg);
94 } else {
95 // We'd really like to avoid a separate data copy, but since
96 // we have allocated messages with headroom, we can't really
97 // make free() work on the base pointer. We'd have to have
98 // some other API for this. Folks that want zero copy had
99 // better use nng_recvmsg() instead.
100 void *nbuf;
101
102 if (nng_msg_len(msg) != 0) {
103 if ((nbuf = nni_alloc(nng_msg_len(msg))) == NULL) {
104 nng_msg_free(msg);
105 return (NNG_ENOMEM);
106 }
107
108 *(void **) buf = nbuf;
109 memcpy(nbuf, nni_msg_body(msg), nni_msg_len(msg));
110 *szp = nng_msg_len(msg);
111 } else {
112 *(void **) buf = NULL;
113 *szp = 0;
114 }
115 }
116 nni_msg_free(msg);
117 return (0);
118 }
119
120 int
nng_recvmsg(nng_socket s,nng_msg ** msgp,int flags)121 nng_recvmsg(nng_socket s, nng_msg **msgp, int flags)
122 {
123 int rv;
124 nng_aio *ap;
125
126 if ((rv = nng_aio_alloc(&ap, NULL, NULL)) != 0) {
127 return (rv);
128 }
129 if (flags & NNG_FLAG_NONBLOCK) {
130 nng_aio_set_timeout(ap, NNG_DURATION_ZERO);
131 } else {
132 nng_aio_set_timeout(ap, NNG_DURATION_DEFAULT);
133 }
134
135 nng_recv_aio(s, ap);
136 nng_aio_wait(ap);
137
138 if ((rv = nng_aio_result(ap)) == 0) {
139 *msgp = nng_aio_get_msg(ap);
140
141 } else if ((rv == NNG_ETIMEDOUT) &&
142 ((flags & NNG_FLAG_NONBLOCK) == NNG_FLAG_NONBLOCK)) {
143 rv = NNG_EAGAIN;
144 }
145 nng_aio_free(ap);
146
147 return (rv);
148 }
149
150 int
nng_send(nng_socket s,void * buf,size_t len,int flags)151 nng_send(nng_socket s, void *buf, size_t len, int flags)
152 {
153 nng_msg *msg;
154 int rv;
155
156 if ((rv = nng_msg_alloc(&msg, len)) != 0) {
157 return (rv);
158 }
159 memcpy(nng_msg_body(msg), buf, len);
160 if ((rv = nng_sendmsg(s, msg, flags)) != 0) {
161 // If nng_sendmsg() succeeded, then it took ownership.
162 nng_msg_free(msg);
163 } else {
164 if (flags & NNG_FLAG_ALLOC) {
165 nni_free(buf, len);
166 }
167 }
168 return (rv);
169 }
170
171 int
nng_sendmsg(nng_socket s,nng_msg * msg,int flags)172 nng_sendmsg(nng_socket s, nng_msg *msg, int flags)
173 {
174 int rv;
175 nng_aio *ap;
176
177 if ((rv = nng_aio_alloc(&ap, NULL, NULL)) != 0) {
178 return (rv);
179 }
180 if ((flags & NNG_FLAG_NONBLOCK) == NNG_FLAG_NONBLOCK) {
181 nng_aio_set_timeout(ap, NNG_DURATION_ZERO);
182 } else {
183 nng_aio_set_timeout(ap, NNG_DURATION_DEFAULT);
184 }
185
186 nng_aio_set_msg(ap, msg);
187 nng_send_aio(s, ap);
188 nng_aio_wait(ap);
189
190 rv = nng_aio_result(ap);
191 nng_aio_free(ap);
192
193 // Possibly massage nonblocking attempt. Note that nonblocking is
194 // still done asynchronously, and the calling thread loses context.
195 if ((rv == NNG_ETIMEDOUT) &&
196 ((flags & NNG_FLAG_NONBLOCK) == NNG_FLAG_NONBLOCK)) {
197 rv = NNG_EAGAIN;
198 }
199
200 return (rv);
201 }
202
203 void
nng_recv_aio(nng_socket s,nng_aio * aio)204 nng_recv_aio(nng_socket s, nng_aio *aio)
205 {
206 nni_sock *sock;
207 int rv;
208
209 if ((rv = nni_sock_find(&sock, s.id)) != 0) {
210 if (nni_aio_begin(aio) == 0) {
211 nni_aio_finish_error(aio, rv);
212 }
213 return;
214 }
215 nni_sock_recv(sock, aio);
216 nni_sock_rele(sock);
217 }
218
219 void
nng_send_aio(nng_socket s,nng_aio * aio)220 nng_send_aio(nng_socket s, nng_aio *aio)
221 {
222 nni_sock *sock;
223 int rv;
224
225 if (nni_aio_get_msg(aio) == NULL) {
226 if (nni_aio_begin(aio) == 0) {
227 nni_aio_finish_error(aio, NNG_EINVAL);
228 }
229 return;
230 }
231 if ((rv = nni_sock_find(&sock, s.id)) != 0) {
232 if (nni_aio_begin(aio) == 0) {
233 nni_aio_finish_error(aio, rv);
234 }
235 return;
236 }
237 nni_sock_send(sock, aio);
238 nni_sock_rele(sock);
239 }
240
241 int
nng_ctx_open(nng_ctx * cp,nng_socket s)242 nng_ctx_open(nng_ctx *cp, nng_socket s)
243 {
244 nni_sock *sock;
245 nni_ctx * ctx;
246 int rv;
247 nng_ctx c;
248
249 if ((rv = nni_sock_find(&sock, s.id)) != 0) {
250 return (rv);
251 }
252 if ((rv = nni_ctx_open(&ctx, sock)) != 0) {
253 nni_sock_rele(sock);
254 return (rv);
255 }
256 c.id = nni_ctx_id(ctx);
257 nni_ctx_rele(ctx);
258 nni_sock_rele(sock);
259 *cp = c;
260 return (0);
261 }
262
263 int
nng_ctx_close(nng_ctx c)264 nng_ctx_close(nng_ctx c)
265 {
266 int rv;
267 nni_ctx *ctx;
268
269 if ((rv = nni_ctx_find(&ctx, c.id, true)) != 0) {
270 return (rv);
271 }
272 // no release, close releases implicitly.
273 nni_ctx_close(ctx);
274 return (0);
275 }
276
277 int
nng_ctx_id(nng_ctx c)278 nng_ctx_id(nng_ctx c)
279 {
280 return (((int) c.id > 0) ? (int) c.id : -1);
281 }
282
283 void
nng_ctx_recv(nng_ctx cid,nng_aio * aio)284 nng_ctx_recv(nng_ctx cid, nng_aio *aio)
285 {
286 int rv;
287 nni_ctx *ctx;
288
289 if ((rv = nni_ctx_find(&ctx, cid.id, false)) != 0) {
290 if (nni_aio_begin(aio) == 0) {
291 nni_aio_finish_error(aio, rv);
292 }
293 return;
294 }
295 nni_ctx_recv(ctx, aio);
296 nni_ctx_rele(ctx);
297 }
298
299 void
nng_ctx_send(nng_ctx cid,nng_aio * aio)300 nng_ctx_send(nng_ctx cid, nng_aio *aio)
301 {
302 int rv;
303 nni_ctx *ctx;
304
305 if (nni_aio_get_msg(aio) == NULL) {
306 if (nni_aio_begin(aio) == 0) {
307 nni_aio_finish_error(aio, NNG_EINVAL);
308 }
309 return;
310 }
311 if ((rv = nni_ctx_find(&ctx, cid.id, false)) != 0) {
312 if (nni_aio_begin(aio) == 0) {
313 nni_aio_finish_error(aio, rv);
314 }
315 return;
316 }
317 nni_ctx_send(ctx, aio);
318 nni_ctx_rele(ctx);
319 }
320
321 static int
ctx_get(nng_ctx id,const char * n,void * v,size_t * szp,nni_type t)322 ctx_get(nng_ctx id, const char *n, void *v, size_t *szp, nni_type t)
323 {
324 nni_ctx *ctx;
325 int rv;
326
327 if ((rv = nni_init()) != 0) {
328 return (rv);
329 }
330 if ((rv = nni_ctx_find(&ctx, id.id, false)) != 0) {
331 return (rv);
332 }
333 rv = nni_ctx_getopt(ctx, n, v, szp, t);
334 nni_ctx_rele(ctx);
335 return (rv);
336 }
337
338 int
nng_ctx_get(nng_ctx id,const char * n,void * v,size_t * szp)339 nng_ctx_get(nng_ctx id, const char *n, void *v, size_t *szp)
340 {
341 return (ctx_get(id, n, v, szp, NNI_TYPE_OPAQUE));
342 }
343
344 int
nng_ctx_get_int(nng_ctx id,const char * n,int * v)345 nng_ctx_get_int(nng_ctx id, const char *n, int *v)
346 {
347 return (ctx_get(id, n, v, NULL, NNI_TYPE_INT32));
348 }
349
350 int
nng_ctx_get_bool(nng_ctx id,const char * n,bool * v)351 nng_ctx_get_bool(nng_ctx id, const char *n, bool *v)
352 {
353 return (ctx_get(id, n, v, NULL, NNI_TYPE_BOOL));
354 }
355
356 int
nng_ctx_get_size(nng_ctx id,const char * n,size_t * v)357 nng_ctx_get_size(nng_ctx id, const char *n, size_t *v)
358 {
359 return (ctx_get(id, n, v, NULL, NNI_TYPE_SIZE));
360 }
361
362 int
nng_ctx_get_uint64(nng_ctx id,const char * n,uint64_t * v)363 nng_ctx_get_uint64(nng_ctx id, const char *n, uint64_t *v)
364 {
365 return (ctx_get(id, n, v, NULL, NNI_TYPE_UINT64));
366 }
367
368 int
nng_ctx_get_string(nng_ctx id,const char * n,char ** v)369 nng_ctx_get_string(nng_ctx id, const char *n, char **v)
370 {
371 return (ctx_get(id, n, v, NULL, NNI_TYPE_STRING));
372 }
373
374 int
nng_ctx_get_ptr(nng_ctx id,const char * n,void ** v)375 nng_ctx_get_ptr(nng_ctx id, const char *n, void **v)
376 {
377 return (ctx_get(id, n, v, NULL, NNI_TYPE_POINTER));
378 }
379
380 int
nng_ctx_get_ms(nng_ctx id,const char * n,nng_duration * v)381 nng_ctx_get_ms(nng_ctx id, const char *n, nng_duration *v)
382 {
383 return (ctx_get(id, n, v, NULL, NNI_TYPE_DURATION));
384 }
385
386 int
nng_ctx_get_addr(nng_ctx id,const char * n,nng_sockaddr * v)387 nng_ctx_get_addr(nng_ctx id, const char *n, nng_sockaddr *v)
388 {
389 return (ctx_get(id, n, v, NULL, NNI_TYPE_SOCKADDR));
390 }
391
392 static int
ctx_set(nng_ctx id,const char * n,const void * v,size_t sz,nni_type t)393 ctx_set(nng_ctx id, const char *n, const void *v, size_t sz, nni_type t)
394 {
395 nni_ctx *ctx;
396 int rv;
397
398 if ((rv = nni_init()) != 0) {
399 return (rv);
400 }
401 if ((rv = nni_ctx_find(&ctx, id.id, false)) != 0) {
402 return (rv);
403 }
404 rv = nni_ctx_setopt(ctx, n, v, sz, t);
405 nni_ctx_rele(ctx);
406 return (rv);
407 }
408
409 int
nng_ctx_set(nng_ctx id,const char * n,const void * v,size_t sz)410 nng_ctx_set(nng_ctx id, const char *n, const void *v, size_t sz)
411 {
412 return (ctx_set(id, n, v, sz, NNI_TYPE_OPAQUE));
413 }
414
415 int
nng_ctx_set_int(nng_ctx id,const char * n,int v)416 nng_ctx_set_int(nng_ctx id, const char *n, int v)
417 {
418 return (ctx_set(id, n, &v, sizeof(v), NNI_TYPE_INT32));
419 }
420
421 int
nng_ctx_set_bool(nng_ctx id,const char * n,bool v)422 nng_ctx_set_bool(nng_ctx id, const char *n, bool v)
423 {
424 return (ctx_set(id, n, &v, sizeof(v), NNI_TYPE_BOOL));
425 }
426
427 int
nng_ctx_set_size(nng_ctx id,const char * n,size_t v)428 nng_ctx_set_size(nng_ctx id, const char *n, size_t v)
429 {
430 return (ctx_set(id, n, &v, sizeof(v), NNI_TYPE_SIZE));
431 }
432
433 int
nng_ctx_set_uint64(nng_ctx id,const char * n,uint64_t v)434 nng_ctx_set_uint64(nng_ctx id, const char *n, uint64_t v)
435 {
436 return (ctx_set(id, n, &v, sizeof(v), NNI_TYPE_UINT64));
437 }
438
439 int
nng_ctx_set_ms(nng_ctx id,const char * n,nng_duration v)440 nng_ctx_set_ms(nng_ctx id, const char *n, nng_duration v)
441 {
442 return (ctx_set(id, n, &v, sizeof(v), NNI_TYPE_DURATION));
443 }
444
445 int
nng_ctx_set_ptr(nng_ctx id,const char * n,void * v)446 nng_ctx_set_ptr(nng_ctx id, const char *n, void *v)
447 {
448 return (ctx_set(id, n, &v, sizeof(v), NNI_TYPE_POINTER));
449 }
450
451 int
nng_ctx_set_string(nng_ctx id,const char * n,const char * v)452 nng_ctx_set_string(nng_ctx id, const char *n, const char *v)
453 {
454 return (
455 ctx_set(id, n, v, v == NULL ? 0 : strlen(v) + 1, NNI_TYPE_STRING));
456 }
457
458 int
nng_ctx_set_addr(nng_ctx id,const char * n,const nng_sockaddr * v)459 nng_ctx_set_addr(nng_ctx id, const char *n, const nng_sockaddr *v)
460 {
461 return (ctx_set(id, n, v, sizeof(*v), NNI_TYPE_SOCKADDR));
462 }
463
464 int
nng_dial(nng_socket sid,const char * addr,nng_dialer * dp,int flags)465 nng_dial(nng_socket sid, const char *addr, nng_dialer *dp, int flags)
466 {
467 nni_dialer *d;
468 int rv;
469 nni_sock * s;
470
471 if ((rv = nni_sock_find(&s, sid.id)) != 0) {
472 return (rv);
473 }
474 if ((rv = nni_dialer_create(&d, s, addr)) != 0) {
475 nni_sock_rele(s);
476 return (rv);
477 }
478 if ((rv = nni_dialer_start(d, flags)) != 0) {
479 nni_dialer_close(d);
480 nni_sock_rele(s);
481 return (rv);
482 }
483 if (dp != NULL) {
484 nng_dialer did;
485 did.id = nni_dialer_id(d);
486 *dp = did;
487 }
488 nni_dialer_rele(d);
489 nni_sock_rele(s);
490 return (0);
491 }
492
493 int
nng_listen(nng_socket sid,const char * addr,nng_listener * lp,int flags)494 nng_listen(nng_socket sid, const char *addr, nng_listener *lp, int flags)
495 {
496 int rv;
497 nni_sock * s;
498 nni_listener *l;
499
500 if ((rv = nni_sock_find(&s, sid.id)) != 0) {
501 return (rv);
502 }
503 if ((rv = nni_listener_create(&l, s, addr)) != 0) {
504 nni_sock_rele(s);
505 return (rv);
506 }
507 if ((rv = nni_listener_start(l, flags)) != 0) {
508 nni_listener_close(l);
509 nni_sock_rele(s);
510 return (rv);
511 }
512
513 if (lp != NULL) {
514 nng_listener lid;
515 lid.id = nni_listener_id(l);
516 *lp = lid;
517 }
518 nni_listener_rele(l);
519 nni_sock_rele(s);
520 return (rv);
521 }
522
523 int
nng_listener_create(nng_listener * lp,nng_socket sid,const char * addr)524 nng_listener_create(nng_listener *lp, nng_socket sid, const char *addr)
525 {
526 nni_sock * s;
527 int rv;
528 nni_listener *l;
529 nng_listener lid;
530
531 if ((rv = nni_sock_find(&s, sid.id)) != 0) {
532 return (rv);
533 }
534 if ((rv = nni_listener_create(&l, s, addr)) != 0) {
535 nni_sock_rele(s);
536 return (rv);
537 }
538 lid.id = nni_listener_id(l);
539 *lp = lid;
540 nni_listener_rele(l);
541 nni_sock_rele(s);
542 return (0);
543 }
544
545 int
nng_listener_start(nng_listener lid,int flags)546 nng_listener_start(nng_listener lid, int flags)
547 {
548 nni_listener *l;
549 int rv;
550
551 if ((rv = nni_listener_find(&l, lid.id)) != 0) {
552 return (rv);
553 }
554 rv = nni_listener_start(l, flags);
555 nni_listener_rele(l);
556 return (rv);
557 }
558
559 int
nng_listener_id(nng_listener l)560 nng_listener_id(nng_listener l)
561 {
562 return (((int) l.id > 0) ? (int) l.id : -1);
563 }
564
565 int
nng_dialer_create(nng_dialer * dp,nng_socket sid,const char * addr)566 nng_dialer_create(nng_dialer *dp, nng_socket sid, const char *addr)
567 {
568 nni_sock * s;
569 nni_dialer *d;
570 int rv;
571 nng_dialer did;
572
573 if ((rv = nni_sock_find(&s, sid.id)) != 0) {
574 return (rv);
575 }
576 if ((rv = nni_dialer_create(&d, s, addr)) != 0) {
577 nni_sock_rele(s);
578 return (rv);
579 }
580 did.id = nni_dialer_id(d);
581 *dp = did;
582 nni_dialer_rele(d);
583 nni_sock_rele(s);
584 return (0);
585 }
586
587 int
nng_dialer_start(nng_dialer did,int flags)588 nng_dialer_start(nng_dialer did, int flags)
589 {
590 nni_dialer *d;
591 int rv;
592
593 if ((rv = nni_dialer_find(&d, did.id)) != 0) {
594 return (rv);
595 }
596 rv = nni_dialer_start(d, flags);
597 nni_dialer_rele(d);
598 return (rv);
599 }
600
601 int
nng_dialer_id(nng_dialer d)602 nng_dialer_id(nng_dialer d)
603 {
604 return (((int) d.id > 0) ? (int) d.id : -1);
605 }
606
607 static int
dialer_set(nng_dialer id,const char * n,const void * v,size_t sz,nni_type t)608 dialer_set(nng_dialer id, const char *n, const void *v, size_t sz, nni_type t)
609 {
610 nni_dialer *d;
611 int rv;
612
613 if ((rv = nni_init()) != 0) {
614 return (rv);
615 }
616 if ((rv = nni_dialer_find(&d, id.id)) != 0) {
617 return (rv);
618 }
619 rv = nni_dialer_setopt(d, n, v, sz, t);
620 nni_dialer_rele(d);
621 return (rv);
622 }
623
624 int
nng_dialer_set(nng_dialer id,const char * n,const void * v,size_t sz)625 nng_dialer_set(nng_dialer id, const char *n, const void *v, size_t sz)
626 {
627 return (dialer_set(id, n, v, sz, NNI_TYPE_OPAQUE));
628 }
629
630 int
nng_dialer_set_int(nng_dialer id,const char * n,int v)631 nng_dialer_set_int(nng_dialer id, const char *n, int v)
632 {
633 return (dialer_set(id, n, &v, sizeof(v), NNI_TYPE_INT32));
634 }
635
636 int
nng_dialer_set_bool(nng_dialer id,const char * n,bool v)637 nng_dialer_set_bool(nng_dialer id, const char *n, bool v)
638 {
639 return (dialer_set(id, n, &v, sizeof(v), NNI_TYPE_BOOL));
640 }
641
642 int
nng_dialer_set_size(nng_dialer id,const char * n,size_t v)643 nng_dialer_set_size(nng_dialer id, const char *n, size_t v)
644 {
645 return (dialer_set(id, n, &v, sizeof(v), NNI_TYPE_SIZE));
646 }
647
648 int
nng_dialer_set_uint64(nng_dialer id,const char * n,uint64_t v)649 nng_dialer_set_uint64(nng_dialer id, const char *n, uint64_t v)
650 {
651 return (dialer_set(id, n, &v, sizeof(v), NNI_TYPE_UINT64));
652 }
653
654 int
nng_dialer_set_ms(nng_dialer id,const char * n,nng_duration v)655 nng_dialer_set_ms(nng_dialer id, const char *n, nng_duration v)
656 {
657 return (dialer_set(id, n, &v, sizeof(v), NNI_TYPE_DURATION));
658 }
659
660 int
nng_dialer_set_ptr(nng_dialer id,const char * n,void * v)661 nng_dialer_set_ptr(nng_dialer id, const char *n, void *v)
662 {
663 return (dialer_set(id, n, &v, sizeof(v), NNI_TYPE_POINTER));
664 }
665
666 int
nng_dialer_set_string(nng_dialer id,const char * n,const char * v)667 nng_dialer_set_string(nng_dialer id, const char *n, const char *v)
668 {
669 return (dialer_set(
670 id, n, v, v == NULL ? 0 : strlen(v) + 1, NNI_TYPE_STRING));
671 }
672
673 int
nng_dialer_set_addr(nng_dialer id,const char * n,const nng_sockaddr * v)674 nng_dialer_set_addr(nng_dialer id, const char *n, const nng_sockaddr *v)
675 {
676 return (dialer_set(id, n, v, sizeof(*v), NNI_TYPE_SOCKADDR));
677 }
678
679 static int
dialer_get(nng_dialer id,const char * n,void * v,size_t * szp,nni_type t)680 dialer_get(nng_dialer id, const char *n, void *v, size_t *szp, nni_type t)
681 {
682 nni_dialer *d;
683 int rv;
684
685 if ((rv = nni_init()) != 0) {
686 return (rv);
687 }
688 if ((rv = nni_dialer_find(&d, id.id)) != 0) {
689 return (rv);
690 }
691 rv = nni_dialer_getopt(d, n, v, szp, t);
692 nni_dialer_rele(d);
693 return (rv);
694 }
695
696 int
nng_dialer_get(nng_dialer id,const char * n,void * v,size_t * szp)697 nng_dialer_get(nng_dialer id, const char *n, void *v, size_t *szp)
698 {
699 return (dialer_get(id, n, v, szp, NNI_TYPE_OPAQUE));
700 }
701
702 int
nng_dialer_get_int(nng_dialer id,const char * n,int * v)703 nng_dialer_get_int(nng_dialer id, const char *n, int *v)
704 {
705 return (dialer_get(id, n, v, NULL, NNI_TYPE_INT32));
706 }
707
708 int
nng_dialer_get_bool(nng_dialer id,const char * n,bool * v)709 nng_dialer_get_bool(nng_dialer id, const char *n, bool *v)
710 {
711 return (dialer_get(id, n, v, NULL, NNI_TYPE_BOOL));
712 }
713
714 int
nng_dialer_get_size(nng_dialer id,const char * n,size_t * v)715 nng_dialer_get_size(nng_dialer id, const char *n, size_t *v)
716 {
717 return (dialer_get(id, n, v, NULL, NNI_TYPE_SIZE));
718 }
719
720 int
nng_dialer_get_uint64(nng_dialer id,const char * n,uint64_t * v)721 nng_dialer_get_uint64(nng_dialer id, const char *n, uint64_t *v)
722 {
723 return (dialer_get(id, n, v, NULL, NNI_TYPE_UINT64));
724 }
725
726 int
nng_dialer_get_string(nng_dialer id,const char * n,char ** v)727 nng_dialer_get_string(nng_dialer id, const char *n, char **v)
728 {
729 return (dialer_get(id, n, v, NULL, NNI_TYPE_STRING));
730 }
731
732 int
nng_dialer_get_ptr(nng_dialer id,const char * n,void ** v)733 nng_dialer_get_ptr(nng_dialer id, const char *n, void **v)
734 {
735 return (dialer_get(id, n, v, NULL, NNI_TYPE_POINTER));
736 }
737
738 int
nng_dialer_get_ms(nng_dialer id,const char * n,nng_duration * v)739 nng_dialer_get_ms(nng_dialer id, const char *n, nng_duration *v)
740 {
741 return (dialer_get(id, n, v, NULL, NNI_TYPE_DURATION));
742 }
743
744 int
nng_dialer_get_addr(nng_dialer id,const char * n,nng_sockaddr * v)745 nng_dialer_get_addr(nng_dialer id, const char *n, nng_sockaddr *v)
746 {
747 return (dialer_get(id, n, v, NULL, NNI_TYPE_SOCKADDR));
748 }
749
750 static int
listener_set(nng_listener lid,const char * name,const void * v,size_t sz,nni_type t)751 listener_set(
752 nng_listener lid, const char *name, const void *v, size_t sz, nni_type t)
753 {
754 nni_listener *l;
755 int rv;
756
757 if ((rv = nni_init()) != 0) {
758 return (rv);
759 }
760 if ((rv = nni_listener_find(&l, lid.id)) != 0) {
761 return (rv);
762 }
763 rv = nni_listener_setopt(l, name, v, sz, t);
764 nni_listener_rele(l);
765 return (rv);
766 }
767
768 int
nng_listener_set(nng_listener id,const char * n,const void * v,size_t sz)769 nng_listener_set(nng_listener id, const char *n, const void *v, size_t sz)
770 {
771 return (listener_set(id, n, v, sz, NNI_TYPE_OPAQUE));
772 }
773
774 int
nng_listener_set_int(nng_listener id,const char * n,int v)775 nng_listener_set_int(nng_listener id, const char *n, int v)
776 {
777 return (listener_set(id, n, &v, sizeof(v), NNI_TYPE_INT32));
778 }
779
780 int
nng_listener_set_bool(nng_listener id,const char * n,bool v)781 nng_listener_set_bool(nng_listener id, const char *n, bool v)
782 {
783 return (listener_set(id, n, &v, sizeof(v), NNI_TYPE_BOOL));
784 }
785
786 int
nng_listener_set_size(nng_listener id,const char * n,size_t v)787 nng_listener_set_size(nng_listener id, const char *n, size_t v)
788 {
789 return (listener_set(id, n, &v, sizeof(v), NNI_TYPE_SIZE));
790 }
791
792 int
nng_listener_set_uint64(nng_listener id,const char * n,uint64_t v)793 nng_listener_set_uint64(nng_listener id, const char *n, uint64_t v)
794 {
795 return (listener_set(id, n, &v, sizeof(v), NNI_TYPE_UINT64));
796 }
797
798 int
nng_listener_set_ms(nng_listener id,const char * n,nng_duration v)799 nng_listener_set_ms(nng_listener id, const char *n, nng_duration v)
800 {
801 return (listener_set(id, n, &v, sizeof(v), NNI_TYPE_DURATION));
802 }
803
804 int
nng_listener_set_ptr(nng_listener id,const char * n,void * v)805 nng_listener_set_ptr(nng_listener id, const char *n, void *v)
806 {
807 return (listener_set(id, n, &v, sizeof(v), NNI_TYPE_POINTER));
808 }
809
810 int
nng_listener_set_string(nng_listener id,const char * n,const char * v)811 nng_listener_set_string(nng_listener id, const char *n, const char *v)
812 {
813 return (listener_set(
814 id, n, v, v == NULL ? 0 : strlen(v) + 1, NNI_TYPE_STRING));
815 }
816
817 int
nng_listener_set_addr(nng_listener id,const char * n,const nng_sockaddr * v)818 nng_listener_set_addr(nng_listener id, const char *n, const nng_sockaddr *v)
819 {
820 return (listener_set(id, n, v, sizeof(*v), NNI_TYPE_SOCKADDR));
821 }
822
823 static int
listener_get(nng_listener lid,const char * name,void * v,size_t * szp,nni_type t)824 listener_get(
825 nng_listener lid, const char *name, void *v, size_t *szp, nni_type t)
826 {
827 nni_listener *l;
828 int rv;
829
830 if ((rv = nni_init()) != 0) {
831 return (rv);
832 }
833 if ((rv = nni_listener_find(&l, lid.id)) != 0) {
834 return (rv);
835 }
836 rv = nni_listener_getopt(l, name, v, szp, t);
837 nni_listener_rele(l);
838 return (rv);
839 }
840
841 int
nng_listener_get(nng_listener id,const char * n,void * v,size_t * szp)842 nng_listener_get(nng_listener id, const char *n, void *v, size_t *szp)
843 {
844 return (listener_get(id, n, v, szp, NNI_TYPE_OPAQUE));
845 }
846
847 int
nng_listener_get_int(nng_listener id,const char * n,int * v)848 nng_listener_get_int(nng_listener id, const char *n, int *v)
849 {
850 return (listener_get(id, n, v, NULL, NNI_TYPE_INT32));
851 }
852
853 int
nng_listener_get_bool(nng_listener id,const char * n,bool * v)854 nng_listener_get_bool(nng_listener id, const char *n, bool *v)
855 {
856 return (listener_get(id, n, v, NULL, NNI_TYPE_BOOL));
857 }
858
859 int
nng_listener_get_size(nng_listener id,const char * n,size_t * v)860 nng_listener_get_size(nng_listener id, const char *n, size_t *v)
861 {
862 return (listener_get(id, n, v, NULL, NNI_TYPE_SIZE));
863 }
864
865 int
nng_listener_get_uint64(nng_listener id,const char * n,uint64_t * v)866 nng_listener_get_uint64(nng_listener id, const char *n, uint64_t *v)
867 {
868 return (listener_get(id, n, v, NULL, NNI_TYPE_UINT64));
869 }
870
871 int
nng_listener_get_string(nng_listener id,const char * n,char ** v)872 nng_listener_get_string(nng_listener id, const char *n, char **v)
873 {
874 return (listener_get(id, n, v, NULL, NNI_TYPE_STRING));
875 }
876
877 int
nng_listener_get_ptr(nng_listener id,const char * n,void ** v)878 nng_listener_get_ptr(nng_listener id, const char *n, void **v)
879 {
880 return (listener_get(id, n, v, NULL, NNI_TYPE_POINTER));
881 }
882
883 int
nng_listener_get_ms(nng_listener id,const char * n,nng_duration * v)884 nng_listener_get_ms(nng_listener id, const char *n, nng_duration *v)
885 {
886 return (listener_get(id, n, v, NULL, NNI_TYPE_DURATION));
887 }
888
889 int
nng_listener_get_addr(nng_listener id,const char * n,nng_sockaddr * v)890 nng_listener_get_addr(nng_listener id, const char *n, nng_sockaddr *v)
891 {
892 return (listener_get(id, n, v, NULL, NNI_TYPE_SOCKADDR));
893 }
894
895 int
nng_dialer_close(nng_dialer did)896 nng_dialer_close(nng_dialer did)
897 {
898 nni_dialer *d;
899 int rv;
900
901 if ((rv = nni_dialer_find(&d, did.id)) != 0) {
902 return (rv);
903 }
904 nni_dialer_close(d);
905 return (0);
906 }
907
908 int
nng_listener_close(nng_listener lid)909 nng_listener_close(nng_listener lid)
910 {
911 nni_listener *l;
912 int rv;
913
914 if ((rv = nni_listener_find(&l, lid.id)) != 0) {
915 return (rv);
916 }
917 nni_listener_close(l);
918 return (0);
919 }
920
921 static int
socket_set(nng_socket s,const char * name,const void * val,size_t sz,nni_type t)922 socket_set(
923 nng_socket s, const char *name, const void *val, size_t sz, nni_type t)
924 {
925 nni_sock *sock;
926 int rv;
927
928 if ((rv = nni_init()) != 0) {
929 return (rv);
930 }
931 if ((rv = nni_sock_find(&sock, s.id)) != 0) {
932 return (rv);
933 }
934 rv = nni_sock_setopt(sock, name, val, sz, t);
935 nni_sock_rele(sock);
936 return (rv);
937 }
938
939 int
nng_socket_set(nng_socket id,const char * n,const void * v,size_t sz)940 nng_socket_set(nng_socket id, const char *n, const void *v, size_t sz)
941 {
942 return (socket_set(id, n, v, sz, NNI_TYPE_OPAQUE));
943 }
944
945 int
nng_socket_set_int(nng_socket id,const char * n,int v)946 nng_socket_set_int(nng_socket id, const char *n, int v)
947 {
948 return (socket_set(id, n, &v, sizeof(v), NNI_TYPE_INT32));
949 }
950
951 int
nng_socket_set_bool(nng_socket id,const char * n,bool v)952 nng_socket_set_bool(nng_socket id, const char *n, bool v)
953 {
954 return (socket_set(id, n, &v, sizeof(v), NNI_TYPE_BOOL));
955 }
956
957 int
nng_socket_set_size(nng_socket id,const char * n,size_t v)958 nng_socket_set_size(nng_socket id, const char *n, size_t v)
959 {
960 return (socket_set(id, n, &v, sizeof(v), NNI_TYPE_SIZE));
961 }
962
963 int
nng_socket_set_uint64(nng_socket id,const char * n,uint64_t v)964 nng_socket_set_uint64(nng_socket id, const char *n, uint64_t v)
965 {
966 return (socket_set(id, n, &v, sizeof(v), NNI_TYPE_UINT64));
967 }
968
969 int
nng_socket_set_ms(nng_socket id,const char * n,nng_duration v)970 nng_socket_set_ms(nng_socket id, const char *n, nng_duration v)
971 {
972 return (socket_set(id, n, &v, sizeof(v), NNI_TYPE_DURATION));
973 }
974
975 int
nng_socket_set_ptr(nng_socket id,const char * n,void * v)976 nng_socket_set_ptr(nng_socket id, const char *n, void *v)
977 {
978 return (socket_set(id, n, &v, sizeof(v), NNI_TYPE_POINTER));
979 }
980
981 int
nng_socket_set_string(nng_socket id,const char * n,const char * v)982 nng_socket_set_string(nng_socket id, const char *n, const char *v)
983 {
984 return (socket_set(
985 id, n, v, v == NULL ? 0 : strlen(v) + 1, NNI_TYPE_STRING));
986 }
987
988 int
nng_socket_set_addr(nng_socket id,const char * n,const nng_sockaddr * v)989 nng_socket_set_addr(nng_socket id, const char *n, const nng_sockaddr *v)
990 {
991 return (socket_set(id, n, v, sizeof(*v), NNI_TYPE_SOCKADDR));
992 }
993
994 static int
socket_get(nng_socket s,const char * name,void * val,size_t * szp,nni_type t)995 socket_get(nng_socket s, const char *name, void *val, size_t *szp, nni_type t)
996 {
997 nni_sock *sock;
998 int rv;
999
1000 if ((rv = nni_init()) != 0) {
1001 return (rv);
1002 }
1003 if ((rv = nni_sock_find(&sock, s.id)) != 0) {
1004 return (rv);
1005 }
1006 rv = nni_sock_getopt(sock, name, val, szp, t);
1007 nni_sock_rele(sock);
1008 return (rv);
1009 }
1010
1011 int
nng_socket_get(nng_socket id,const char * n,void * v,size_t * szp)1012 nng_socket_get(nng_socket id, const char *n, void *v, size_t *szp)
1013 {
1014 return (socket_get(id, n, v, szp, NNI_TYPE_OPAQUE));
1015 }
1016
1017 int
nng_socket_get_int(nng_socket id,const char * n,int * v)1018 nng_socket_get_int(nng_socket id, const char *n, int *v)
1019 {
1020 return (socket_get(id, n, v, NULL, NNI_TYPE_INT32));
1021 }
1022
1023 int
nng_socket_get_bool(nng_socket id,const char * n,bool * v)1024 nng_socket_get_bool(nng_socket id, const char *n, bool *v)
1025 {
1026 return (socket_get(id, n, v, NULL, NNI_TYPE_BOOL));
1027 }
1028
1029 int
nng_socket_get_size(nng_socket id,const char * n,size_t * v)1030 nng_socket_get_size(nng_socket id, const char *n, size_t *v)
1031 {
1032 return (socket_get(id, n, v, NULL, NNI_TYPE_SIZE));
1033 }
1034
1035 int
nng_socket_get_uint64(nng_socket id,const char * n,uint64_t * v)1036 nng_socket_get_uint64(nng_socket id, const char *n, uint64_t *v)
1037 {
1038 return (socket_get(id, n, v, NULL, NNI_TYPE_UINT64));
1039 }
1040
1041 int
nng_socket_get_string(nng_socket id,const char * n,char ** v)1042 nng_socket_get_string(nng_socket id, const char *n, char **v)
1043 {
1044 return (socket_get(id, n, v, NULL, NNI_TYPE_STRING));
1045 }
1046
1047 int
nng_socket_get_ptr(nng_socket id,const char * n,void ** v)1048 nng_socket_get_ptr(nng_socket id, const char *n, void **v)
1049 {
1050 return (socket_get(id, n, v, NULL, NNI_TYPE_POINTER));
1051 }
1052
1053 int
nng_socket_get_ms(nng_socket id,const char * n,nng_duration * v)1054 nng_socket_get_ms(nng_socket id, const char *n, nng_duration *v)
1055 {
1056 return (socket_get(id, n, v, NULL, NNI_TYPE_DURATION));
1057 }
1058
1059 int
nng_socket_get_addr(nng_socket id,const char * n,nng_sockaddr * v)1060 nng_socket_get_addr(nng_socket id, const char *n, nng_sockaddr *v)
1061 {
1062 return (socket_get(id, n, v, NULL, NNI_TYPE_SOCKADDR));
1063 }
1064
1065 int
nng_pipe_notify(nng_socket s,nng_pipe_ev ev,nng_pipe_cb cb,void * arg)1066 nng_pipe_notify(nng_socket s, nng_pipe_ev ev, nng_pipe_cb cb, void *arg)
1067 {
1068 int rv;
1069 nni_sock *sock;
1070
1071 if ((rv = nni_init()) != 0) {
1072 return (rv);
1073 }
1074 if ((rv = nni_sock_find(&sock, s.id)) != 0) {
1075 return (rv);
1076 }
1077
1078 nni_sock_set_pipe_cb(sock, ev, cb, arg);
1079 nni_sock_rele(sock);
1080 return (0);
1081 }
1082
1083 int
nng_device(nng_socket s1,nng_socket s2)1084 nng_device(nng_socket s1, nng_socket s2)
1085 {
1086 int rv;
1087 nni_sock *sock1 = NULL;
1088 nni_sock *sock2 = NULL;
1089
1090 if ((s1.id > 0) && (s1.id != (uint32_t) -1)) {
1091 if ((rv = nni_sock_find(&sock1, s1.id)) != 0) {
1092 return (rv);
1093 }
1094 }
1095 if (((s2.id > 0) && (s2.id != (uint32_t) -1)) && (s2.id != s1.id)) {
1096 if ((rv = nni_sock_find(&sock2, s2.id)) != 0) {
1097 nni_sock_rele(sock1);
1098 return (rv);
1099 }
1100 }
1101
1102 rv = nni_device(sock1, sock2);
1103 if (sock1 != NULL) {
1104 nni_sock_rele(sock1);
1105 }
1106 if (sock2 != NULL) {
1107 nni_sock_rele(sock2);
1108 }
1109 return (rv);
1110 }
1111
1112 static const struct {
1113 int code;
1114 const char *msg;
1115 } nni_errors[] = {
1116 // clang-format off
1117 { 0, "Hunky dory" },
1118 { NNG_EINTR, "Interrupted" },
1119 { NNG_ENOMEM, "Out of memory" },
1120 { NNG_EINVAL, "Invalid argument" },
1121 { NNG_EBUSY, "Resource busy" },
1122 { NNG_ETIMEDOUT, "Timed out" },
1123 { NNG_ECONNREFUSED, "Connection refused" },
1124 { NNG_ECLOSED, "Object closed" },
1125 { NNG_EAGAIN, "Try again" },
1126 { NNG_ENOTSUP, "Not supported" },
1127 { NNG_EADDRINUSE, "Address in use" },
1128 { NNG_ESTATE, "Incorrect state" },
1129 { NNG_ENOENT, "Entry not found" },
1130 { NNG_EPROTO, "Protocol error" },
1131 { NNG_EUNREACHABLE, "Destination unreachable" },
1132 { NNG_EADDRINVAL, "Address invalid" },
1133 { NNG_EPERM, "Permission denied" },
1134 { NNG_EMSGSIZE, "Message too large" },
1135 { NNG_ECONNRESET, "Connection reset" },
1136 { NNG_ECONNABORTED, "Connection aborted" },
1137 { NNG_ECANCELED, "Operation canceled" },
1138 { NNG_ENOFILES, "Out of files" },
1139 { NNG_ENOSPC, "Out of space" },
1140 { NNG_EEXIST, "Resource already exists" },
1141 { NNG_EREADONLY, "Read only resource" },
1142 { NNG_EWRITEONLY, "Write only resource" },
1143 { NNG_ECRYPTO, "Cryptographic error" },
1144 { NNG_EPEERAUTH, "Peer could not be authenticated" },
1145 { NNG_ENOARG, "Option requires argument" },
1146 { NNG_EAMBIGUOUS, "Ambiguous option" },
1147 { NNG_EBADTYPE, "Incorrect type" },
1148 { NNG_ECONNSHUT, "Connection shutdown" },
1149 { NNG_EINTERNAL, "Internal error detected" },
1150 { 0, NULL },
1151 // clang-format on
1152 };
1153
1154 // Misc.
1155 const char *
nng_strerror(int num)1156 nng_strerror(int num)
1157 {
1158 static char unknownerrbuf[32];
1159 for (int i = 0; nni_errors[i].msg != NULL; i++) {
1160 if (nni_errors[i].code == num) {
1161 return (nni_errors[i].msg);
1162 }
1163 }
1164
1165 if (num & NNG_ESYSERR) {
1166 return (nni_plat_strerror(num & ~NNG_ESYSERR));
1167 }
1168
1169 if (num & NNG_ETRANERR) {
1170 static char tranerrbuf[32];
1171 (void) snprintf(tranerrbuf, sizeof(tranerrbuf),
1172 "Transport error #%d", num & ~NNG_ETRANERR);
1173 return (tranerrbuf);
1174 }
1175
1176 (void) snprintf(
1177 unknownerrbuf, sizeof(unknownerrbuf), "Unknown error #%d", num);
1178 return (unknownerrbuf);
1179 }
1180
1181 static int
pipe_get(nng_pipe p,const char * name,void * val,size_t * szp,nni_type t)1182 pipe_get(nng_pipe p, const char *name, void *val, size_t *szp, nni_type t)
1183 {
1184 int rv;
1185 nni_pipe *pipe;
1186
1187 if ((rv = nni_init()) < 0) {
1188 return (rv);
1189 }
1190 if ((rv = nni_pipe_find(&pipe, p.id)) != 0) {
1191 return (rv);
1192 }
1193 rv = nni_pipe_getopt(pipe, name, val, szp, t);
1194 nni_pipe_rele(pipe);
1195 return (rv);
1196 }
1197
1198 int
nng_pipe_get(nng_pipe id,const char * n,void * v,size_t * szp)1199 nng_pipe_get(nng_pipe id, const char *n, void *v, size_t *szp)
1200 {
1201 return (pipe_get(id, n, v, szp, NNI_TYPE_OPAQUE));
1202 }
1203
1204 int
nng_pipe_get_int(nng_pipe id,const char * n,int * v)1205 nng_pipe_get_int(nng_pipe id, const char *n, int *v)
1206 {
1207 return (pipe_get(id, n, v, NULL, NNI_TYPE_INT32));
1208 }
1209
1210 int
nng_pipe_get_bool(nng_pipe id,const char * n,bool * v)1211 nng_pipe_get_bool(nng_pipe id, const char *n, bool *v)
1212 {
1213 return (pipe_get(id, n, v, NULL, NNI_TYPE_BOOL));
1214 }
1215
1216 int
nng_pipe_get_size(nng_pipe id,const char * n,size_t * v)1217 nng_pipe_get_size(nng_pipe id, const char *n, size_t *v)
1218 {
1219 return (pipe_get(id, n, v, NULL, NNI_TYPE_SIZE));
1220 }
1221
1222 int
nng_pipe_get_uint64(nng_pipe id,const char * n,uint64_t * v)1223 nng_pipe_get_uint64(nng_pipe id, const char *n, uint64_t *v)
1224 {
1225 return (pipe_get(id, n, v, NULL, NNI_TYPE_UINT64));
1226 }
1227
1228 int
nng_pipe_get_string(nng_pipe id,const char * n,char ** v)1229 nng_pipe_get_string(nng_pipe id, const char *n, char **v)
1230 {
1231 return (pipe_get(id, n, v, NULL, NNI_TYPE_STRING));
1232 }
1233
1234 int
nng_pipe_get_ptr(nng_pipe id,const char * n,void ** v)1235 nng_pipe_get_ptr(nng_pipe id, const char *n, void **v)
1236 {
1237 return (pipe_get(id, n, v, NULL, NNI_TYPE_POINTER));
1238 }
1239
1240 int
nng_pipe_get_ms(nng_pipe id,const char * n,nng_duration * v)1241 nng_pipe_get_ms(nng_pipe id, const char *n, nng_duration *v)
1242 {
1243 return (pipe_get(id, n, v, NULL, NNI_TYPE_DURATION));
1244 }
1245
1246 int
nng_pipe_get_addr(nng_pipe id,const char * n,nng_sockaddr * v)1247 nng_pipe_get_addr(nng_pipe id, const char *n, nng_sockaddr *v)
1248 {
1249 return (pipe_get(id, n, v, NULL, NNI_TYPE_SOCKADDR));
1250 }
1251
1252 nng_socket
nng_pipe_socket(nng_pipe p)1253 nng_pipe_socket(nng_pipe p)
1254 {
1255 nng_socket s = NNG_SOCKET_INITIALIZER;
1256 nni_pipe * pipe;
1257
1258 if ((nni_init() == 0) && (nni_pipe_find(&pipe, p.id) == 0)) {
1259 s.id = nni_pipe_sock_id(pipe);
1260 nni_pipe_rele(pipe);
1261 }
1262 return (s);
1263 }
1264
1265 nng_dialer
nng_pipe_dialer(nng_pipe p)1266 nng_pipe_dialer(nng_pipe p)
1267 {
1268 nng_dialer d = NNG_DIALER_INITIALIZER;
1269 nni_pipe * pipe;
1270 if ((nni_init() == 0) && (nni_pipe_find(&pipe, p.id) == 0)) {
1271 d.id = nni_pipe_dialer_id(pipe);
1272 nni_pipe_rele(pipe);
1273 }
1274 return (d);
1275 }
1276
1277 nng_listener
nng_pipe_listener(nng_pipe p)1278 nng_pipe_listener(nng_pipe p)
1279 {
1280 nng_listener l = NNG_LISTENER_INITIALIZER;
1281 nni_pipe * pipe;
1282 if ((nni_init() == 0) && (nni_pipe_find(&pipe, p.id) == 0)) {
1283 l.id = nni_pipe_listener_id(pipe);
1284 nni_pipe_rele(pipe);
1285 }
1286 return (l);
1287 }
1288
1289 int
nng_pipe_close(nng_pipe p)1290 nng_pipe_close(nng_pipe p)
1291 {
1292 int rv;
1293 nni_pipe *pipe;
1294
1295 if ((rv = nni_pipe_find(&pipe, p.id)) != 0) {
1296 return (rv);
1297 }
1298 nni_pipe_close(pipe);
1299 nni_pipe_rele(pipe);
1300 return (0);
1301 }
1302
1303 int
nng_pipe_id(nng_pipe p)1304 nng_pipe_id(nng_pipe p)
1305 {
1306 return (((int) p.id > 0) ? (int) p.id : -1);
1307 }
1308
1309 // Message handling.
1310 int
nng_msg_alloc(nng_msg ** msgp,size_t size)1311 nng_msg_alloc(nng_msg **msgp, size_t size)
1312 {
1313 return (nni_msg_alloc(msgp, size));
1314 }
1315
1316 int
nng_msg_realloc(nng_msg * msg,size_t sz)1317 nng_msg_realloc(nng_msg *msg, size_t sz)
1318 {
1319 return (nni_msg_realloc(msg, sz));
1320 }
1321
1322 void
nng_msg_free(nng_msg * msg)1323 nng_msg_free(nng_msg *msg)
1324 {
1325 nni_msg_free(msg);
1326 }
1327
1328 int
nng_msg_reserve(nng_msg * msg,size_t capacity)1329 nng_msg_reserve(nng_msg *msg, size_t capacity)
1330 {
1331 return (nni_msg_reserve(msg, capacity));
1332 }
1333
1334 size_t
nng_msg_capacity(nng_msg * msg)1335 nng_msg_capacity(nng_msg *msg)
1336 {
1337 return (nni_msg_capacity(msg));
1338 }
1339
1340 void *
nng_msg_body(nng_msg * msg)1341 nng_msg_body(nng_msg *msg)
1342 {
1343 return (nni_msg_body(msg));
1344 }
1345
1346 size_t
nng_msg_len(const nng_msg * msg)1347 nng_msg_len(const nng_msg *msg)
1348 {
1349 return (nni_msg_len(msg));
1350 }
1351
1352 void *
nng_msg_header(nng_msg * msg)1353 nng_msg_header(nng_msg *msg)
1354 {
1355 return (nni_msg_header(msg));
1356 }
1357
1358 size_t
nng_msg_header_len(const nng_msg * msg)1359 nng_msg_header_len(const nng_msg *msg)
1360 {
1361 return (nni_msg_header_len(msg));
1362 }
1363
1364 int
nng_msg_append(nng_msg * msg,const void * data,size_t sz)1365 nng_msg_append(nng_msg *msg, const void *data, size_t sz)
1366 {
1367 return (nni_msg_append(msg, data, sz));
1368 }
1369
1370 int
nng_msg_insert(nng_msg * msg,const void * data,size_t sz)1371 nng_msg_insert(nng_msg *msg, const void *data, size_t sz)
1372 {
1373 return (nni_msg_insert(msg, data, sz));
1374 }
1375
1376 int
nng_msg_append_u16(nng_msg * msg,uint16_t v)1377 nng_msg_append_u16(nng_msg *msg, uint16_t v)
1378 {
1379 uint8_t buf[sizeof(v)];
1380 NNI_PUT16(buf, v);
1381 return (nni_msg_append(msg, buf, sizeof(v)));
1382 }
1383
1384 int
nng_msg_append_u32(nng_msg * msg,uint32_t v)1385 nng_msg_append_u32(nng_msg *msg, uint32_t v)
1386 {
1387 uint8_t buf[sizeof(v)];
1388 NNI_PUT32(buf, v);
1389 return (nni_msg_append(msg, buf, sizeof(v)));
1390 }
1391
1392 int
nng_msg_append_u64(nng_msg * msg,uint64_t v)1393 nng_msg_append_u64(nng_msg *msg, uint64_t v)
1394 {
1395 uint8_t buf[sizeof(v)];
1396 NNI_PUT64(buf, v);
1397 return (nni_msg_append(msg, buf, sizeof(v)));
1398 }
1399
1400 int
nng_msg_insert_u16(nng_msg * msg,uint16_t v)1401 nng_msg_insert_u16(nng_msg *msg, uint16_t v)
1402 {
1403 uint8_t buf[sizeof(v)];
1404 NNI_PUT16(buf, v);
1405 return (nni_msg_insert(msg, buf, sizeof(v)));
1406 }
1407
1408 int
nng_msg_insert_u32(nng_msg * msg,uint32_t v)1409 nng_msg_insert_u32(nng_msg *msg, uint32_t v)
1410 {
1411 uint8_t buf[sizeof(v)];
1412 NNI_PUT32(buf, v);
1413 return (nni_msg_insert(msg, buf, sizeof(v)));
1414 }
1415
1416 int
nng_msg_insert_u64(nng_msg * msg,uint64_t v)1417 nng_msg_insert_u64(nng_msg *msg, uint64_t v)
1418 {
1419 uint8_t buf[sizeof(v)];
1420 NNI_PUT64(buf, v);
1421 return (nni_msg_insert(msg, buf, sizeof(v)));
1422 }
1423
1424 int
nng_msg_header_append(nng_msg * msg,const void * data,size_t sz)1425 nng_msg_header_append(nng_msg *msg, const void *data, size_t sz)
1426 {
1427 return (nni_msg_header_append(msg, data, sz));
1428 }
1429
1430 int
nng_msg_header_insert(nng_msg * msg,const void * data,size_t sz)1431 nng_msg_header_insert(nng_msg *msg, const void *data, size_t sz)
1432 {
1433 return (nni_msg_header_insert(msg, data, sz));
1434 }
1435
1436 int
nng_msg_header_append_u16(nng_msg * msg,uint16_t v)1437 nng_msg_header_append_u16(nng_msg *msg, uint16_t v)
1438 {
1439 uint8_t buf[sizeof(v)];
1440 NNI_PUT16(buf, v);
1441 return (nni_msg_header_append(msg, buf, sizeof(v)));
1442 }
1443
1444 int
nng_msg_header_append_u32(nng_msg * msg,uint32_t v)1445 nng_msg_header_append_u32(nng_msg *msg, uint32_t v)
1446 {
1447 uint8_t buf[sizeof(v)];
1448 NNI_PUT32(buf, v);
1449 return (nni_msg_header_append(msg, buf, sizeof(v)));
1450 }
1451
1452 int
nng_msg_header_append_u64(nng_msg * msg,uint64_t v)1453 nng_msg_header_append_u64(nng_msg *msg, uint64_t v)
1454 {
1455 uint8_t buf[sizeof(v)];
1456 NNI_PUT64(buf, v);
1457 return (nni_msg_header_append(msg, buf, sizeof(v)));
1458 }
1459
1460 int
nng_msg_header_insert_u16(nng_msg * msg,uint16_t v)1461 nng_msg_header_insert_u16(nng_msg *msg, uint16_t v)
1462 {
1463 uint8_t buf[sizeof(v)];
1464 NNI_PUT16(buf, v);
1465 return (nni_msg_header_insert(msg, buf, sizeof(v)));
1466 }
1467
1468 int
nng_msg_header_insert_u32(nng_msg * msg,uint32_t v)1469 nng_msg_header_insert_u32(nng_msg *msg, uint32_t v)
1470 {
1471 uint8_t buf[sizeof(v)];
1472 NNI_PUT32(buf, v);
1473 return (nni_msg_header_insert(msg, buf, sizeof(v)));
1474 }
1475
1476 int
nng_msg_header_insert_u64(nng_msg * msg,uint64_t v)1477 nng_msg_header_insert_u64(nng_msg *msg, uint64_t v)
1478 {
1479 uint8_t buf[sizeof(v)];
1480 NNI_PUT64(buf, v);
1481 return (nni_msg_header_insert(msg, buf, sizeof(v)));
1482 }
1483
1484 int
nng_msg_trim(nng_msg * msg,size_t sz)1485 nng_msg_trim(nng_msg *msg, size_t sz)
1486 {
1487 return (nni_msg_trim(msg, sz));
1488 }
1489
1490 int
nng_msg_chop(nng_msg * msg,size_t sz)1491 nng_msg_chop(nng_msg *msg, size_t sz)
1492 {
1493 return (nni_msg_chop(msg, sz));
1494 }
1495
1496 int
nng_msg_header_trim(nng_msg * msg,size_t sz)1497 nng_msg_header_trim(nng_msg *msg, size_t sz)
1498 {
1499 return (nni_msg_header_trim(msg, sz));
1500 }
1501
1502 int
nng_msg_header_chop(nng_msg * msg,size_t sz)1503 nng_msg_header_chop(nng_msg *msg, size_t sz)
1504 {
1505 return (nni_msg_header_chop(msg, sz));
1506 }
1507
1508 int
nng_msg_chop_u16(nng_msg * m,uint16_t * vp)1509 nng_msg_chop_u16(nng_msg *m, uint16_t *vp)
1510 {
1511 uint8_t *body;
1512 uint16_t v;
1513 if (nni_msg_len(m) < sizeof(*vp)) {
1514 return (NNG_EINVAL);
1515 }
1516 body = nni_msg_body(m);
1517 body += nni_msg_len(m);
1518 body -= sizeof(v);
1519 NNI_GET16(body, v);
1520 (void) nni_msg_chop(m, sizeof(v));
1521 *vp = v;
1522 return (0);
1523 }
1524
1525 int
nng_msg_chop_u32(nng_msg * m,uint32_t * vp)1526 nng_msg_chop_u32(nng_msg *m, uint32_t *vp)
1527 {
1528 uint8_t *body;
1529 uint32_t v;
1530 if (nni_msg_len(m) < sizeof(*vp)) {
1531 return (NNG_EINVAL);
1532 }
1533 body = nni_msg_body(m);
1534 body += nni_msg_len(m);
1535 body -= sizeof(v);
1536 NNI_GET32(body, v);
1537 (void) nni_msg_chop(m, sizeof(v));
1538 *vp = v;
1539 return (0);
1540 }
1541
1542 int
nng_msg_chop_u64(nng_msg * m,uint64_t * vp)1543 nng_msg_chop_u64(nng_msg *m, uint64_t *vp)
1544 {
1545 uint8_t *body;
1546 uint64_t v;
1547 if (nni_msg_len(m) < sizeof(*vp)) {
1548 return (NNG_EINVAL);
1549 }
1550 body = nni_msg_body(m);
1551 body += nni_msg_len(m);
1552 body -= sizeof(v);
1553 NNI_GET64(body, v);
1554 (void) nni_msg_chop(m, sizeof(v));
1555 *vp = v;
1556 return (0);
1557 }
1558
1559 int
nng_msg_trim_u16(nng_msg * m,uint16_t * vp)1560 nng_msg_trim_u16(nng_msg *m, uint16_t *vp)
1561 {
1562 uint8_t *body;
1563 uint16_t v;
1564 if (nni_msg_len(m) < sizeof(v)) {
1565 return (NNG_EINVAL);
1566 }
1567 body = nni_msg_body(m);
1568 NNI_GET16(body, v);
1569 (void) nni_msg_trim(m, sizeof(v));
1570 *vp = v;
1571 return (0);
1572 }
1573
1574 int
nng_msg_trim_u32(nng_msg * m,uint32_t * vp)1575 nng_msg_trim_u32(nng_msg *m, uint32_t *vp)
1576 {
1577 uint8_t *body;
1578 uint32_t v;
1579 if (nni_msg_len(m) < sizeof(v)) {
1580 return (NNG_EINVAL);
1581 }
1582 body = nni_msg_body(m);
1583 NNI_GET32(body, v);
1584 (void) nni_msg_trim(m, sizeof(v));
1585 *vp = v;
1586 return (0);
1587 }
1588
1589 int
nng_msg_trim_u64(nng_msg * m,uint64_t * vp)1590 nng_msg_trim_u64(nng_msg *m, uint64_t *vp)
1591 {
1592 uint8_t *body;
1593 uint64_t v;
1594 if (nni_msg_len(m) < sizeof(v)) {
1595 return (NNG_EINVAL);
1596 }
1597 body = nni_msg_body(m);
1598 NNI_GET64(body, v);
1599 (void) nni_msg_trim(m, sizeof(v));
1600 *vp = v;
1601 return (0);
1602 }
1603
1604 int
nng_msg_header_chop_u16(nng_msg * msg,uint16_t * val)1605 nng_msg_header_chop_u16(nng_msg *msg, uint16_t *val)
1606 {
1607 uint8_t *header;
1608 uint16_t v;
1609 if (nng_msg_header_len(msg) < sizeof(*val)) {
1610 return (NNG_EINVAL);
1611 }
1612 header = nng_msg_header(msg);
1613 header += nng_msg_header_len(msg);
1614 header -= sizeof(v);
1615 NNI_GET16(header, v);
1616 *val = v;
1617 nni_msg_header_chop(msg, sizeof(v));
1618 return (0);
1619 }
1620
1621 int
nng_msg_header_chop_u32(nng_msg * msg,uint32_t * val)1622 nng_msg_header_chop_u32(nng_msg *msg, uint32_t *val)
1623 {
1624 uint8_t *header;
1625 uint32_t v;
1626 if (nng_msg_header_len(msg) < sizeof(*val)) {
1627 return (NNG_EINVAL);
1628 }
1629 header = nng_msg_header(msg);
1630 header += nng_msg_header_len(msg);
1631 header -= sizeof(v);
1632 NNI_GET32(header, v);
1633 *val = v;
1634 nni_msg_header_chop(msg, sizeof(v));
1635 return (0);
1636 }
1637
1638 int
nng_msg_header_chop_u64(nng_msg * msg,uint64_t * val)1639 nng_msg_header_chop_u64(nng_msg *msg, uint64_t *val)
1640 {
1641 uint8_t *header;
1642 uint64_t v;
1643 if (nng_msg_header_len(msg) < sizeof(v)) {
1644 return (NNG_EINVAL);
1645 }
1646 header = nng_msg_header(msg);
1647 header += nng_msg_header_len(msg);
1648 header -= sizeof(v);
1649 NNI_GET64(header, v);
1650 *val = v;
1651 nni_msg_header_chop(msg, sizeof(*val));
1652 return (0);
1653 }
1654
1655 int
nng_msg_header_trim_u16(nng_msg * msg,uint16_t * val)1656 nng_msg_header_trim_u16(nng_msg *msg, uint16_t *val)
1657 {
1658 uint8_t *header = nni_msg_header(msg);
1659 uint16_t v;
1660 if (nng_msg_header_len(msg) < sizeof(v)) {
1661 return (NNG_EINVAL);
1662 }
1663 NNI_GET16(header, v);
1664 *val = v;
1665 nni_msg_header_trim(msg, sizeof(v));
1666 return (0);
1667 }
1668
1669 int
nng_msg_header_trim_u32(nng_msg * msg,uint32_t * val)1670 nng_msg_header_trim_u32(nng_msg *msg, uint32_t *val)
1671 {
1672 uint8_t *header = nni_msg_header(msg);
1673 uint32_t v;
1674 if (nng_msg_header_len(msg) < sizeof(v)) {
1675 return (NNG_EINVAL);
1676 }
1677 NNI_GET32(header, v);
1678 *val = v;
1679 nni_msg_header_trim(msg, sizeof(v));
1680 return (0);
1681 }
1682
1683 int
nng_msg_header_trim_u64(nng_msg * msg,uint64_t * val)1684 nng_msg_header_trim_u64(nng_msg *msg, uint64_t *val)
1685 {
1686 uint8_t *header = nni_msg_header(msg);
1687 uint64_t v;
1688 if (nng_msg_header_len(msg) < sizeof(v)) {
1689 return (NNG_EINVAL);
1690 }
1691 NNI_GET64(header, v);
1692 *val = v;
1693 nni_msg_header_trim(msg, sizeof(v));
1694 return (0);
1695 }
1696
1697 void
nng_msg_clear(nng_msg * msg)1698 nng_msg_clear(nng_msg *msg)
1699 {
1700 nni_msg_clear(msg);
1701 }
1702
1703 void
nng_msg_header_clear(nng_msg * msg)1704 nng_msg_header_clear(nng_msg *msg)
1705 {
1706 nni_msg_header_clear(msg);
1707 }
1708
1709 int
nng_msg_dup(nng_msg ** dup,const nng_msg * src)1710 nng_msg_dup(nng_msg **dup, const nng_msg *src)
1711 {
1712 return (nni_msg_dup(dup, src));
1713 }
1714
1715 nng_pipe
nng_msg_get_pipe(const nng_msg * msg)1716 nng_msg_get_pipe(const nng_msg *msg)
1717 {
1718 nng_pipe p;
1719 p.id = nni_msg_get_pipe(msg);
1720 return (p);
1721 }
1722
1723 void
nng_msg_set_pipe(nng_msg * msg,nng_pipe p)1724 nng_msg_set_pipe(nng_msg *msg, nng_pipe p)
1725 {
1726 nni_msg_set_pipe(msg, p.id);
1727 }
1728
1729 int
nng_aio_alloc(nng_aio ** app,void (* cb)(void *),void * arg)1730 nng_aio_alloc(nng_aio **app, void (*cb)(void *), void *arg)
1731 {
1732 nng_aio *aio;
1733 int rv;
1734
1735 if ((rv = nni_init()) != 0) {
1736 return (rv);
1737 }
1738 if ((rv = nni_aio_alloc(&aio, (nni_cb) cb, arg)) == 0) {
1739 nng_aio_set_timeout(aio, NNG_DURATION_DEFAULT);
1740 *app = aio;
1741 }
1742 return (rv);
1743 }
1744
1745 void
nng_aio_free(nng_aio * aio)1746 nng_aio_free(nng_aio *aio)
1747 {
1748 nni_aio_free(aio);
1749 }
1750
1751 void
nng_aio_reap(nng_aio * aio)1752 nng_aio_reap(nng_aio *aio)
1753 {
1754 nni_aio_reap(aio);
1755 }
1756
1757 void
nng_sleep_aio(nng_duration ms,nng_aio * aio)1758 nng_sleep_aio(nng_duration ms, nng_aio *aio)
1759 {
1760 nni_sleep_aio(ms, aio);
1761 }
1762
1763 int
nng_aio_result(nng_aio * aio)1764 nng_aio_result(nng_aio *aio)
1765 {
1766 return (nni_aio_result(aio));
1767 }
1768
1769 size_t
nng_aio_count(nng_aio * aio)1770 nng_aio_count(nng_aio *aio)
1771 {
1772 return (nni_aio_count(aio));
1773 }
1774
1775 void
nng_aio_stop(nng_aio * aio)1776 nng_aio_stop(nng_aio *aio)
1777 {
1778 nni_aio_stop(aio);
1779 }
1780
1781 void
nng_aio_wait(nng_aio * aio)1782 nng_aio_wait(nng_aio *aio)
1783 {
1784 nni_aio_wait(aio);
1785 }
1786
1787 void
nng_aio_abort(nng_aio * aio,int err_code)1788 nng_aio_abort(nng_aio *aio, int err_code)
1789 {
1790 nni_aio_abort(aio, err_code);
1791 }
1792
1793 void
nng_aio_cancel(nng_aio * aio)1794 nng_aio_cancel(nng_aio *aio)
1795 {
1796 nni_aio_abort(aio, NNG_ECANCELED);
1797 }
1798
1799 void
nng_aio_set_msg(nng_aio * aio,nng_msg * msg)1800 nng_aio_set_msg(nng_aio *aio, nng_msg *msg)
1801 {
1802 nni_aio_set_msg(aio, msg);
1803 }
1804
1805 nng_msg *
nng_aio_get_msg(nng_aio * aio)1806 nng_aio_get_msg(nng_aio *aio)
1807 {
1808 return (nni_aio_get_msg(aio));
1809 }
1810
1811 void
nng_aio_set_timeout(nng_aio * aio,nni_duration when)1812 nng_aio_set_timeout(nng_aio *aio, nni_duration when)
1813 {
1814 nni_aio_set_timeout(aio, when);
1815 }
1816
1817 int
nng_aio_set_iov(nng_aio * aio,unsigned niov,const nng_iov * iov)1818 nng_aio_set_iov(nng_aio *aio, unsigned niov, const nng_iov *iov)
1819 {
1820 return (nni_aio_set_iov(aio, niov, iov));
1821 }
1822
1823 int
nng_aio_set_input(nng_aio * aio,unsigned index,void * arg)1824 nng_aio_set_input(nng_aio *aio, unsigned index, void *arg)
1825 {
1826 if (index > 3) {
1827 return (NNG_EINVAL);
1828 }
1829 nni_aio_set_input(aio, index, arg);
1830 return (0);
1831 }
1832 int
nng_aio_set_output(nng_aio * aio,unsigned index,void * arg)1833 nng_aio_set_output(nng_aio *aio, unsigned index, void *arg)
1834 {
1835 if (index > 3) {
1836 return (NNG_EINVAL);
1837 }
1838 nni_aio_set_output(aio, index, arg);
1839 return (0);
1840 }
1841
1842 void *
nng_aio_get_input(nng_aio * aio,unsigned index)1843 nng_aio_get_input(nng_aio *aio, unsigned index)
1844 {
1845 return (nni_aio_get_input(aio, index));
1846 }
1847
1848 void *
nng_aio_get_output(nng_aio * aio,unsigned index)1849 nng_aio_get_output(nng_aio *aio, unsigned index)
1850 {
1851 return (nni_aio_get_output(aio, index));
1852 }
1853
1854 void
nng_aio_finish(nng_aio * aio,int rv)1855 nng_aio_finish(nng_aio *aio, int rv)
1856 {
1857 // Preserve the count.
1858 nni_aio_finish(aio, rv, nni_aio_count(aio));
1859 }
1860
1861 void
nng_aio_defer(nng_aio * aio,nng_aio_cancelfn fn,void * arg)1862 nng_aio_defer(nng_aio *aio, nng_aio_cancelfn fn, void *arg)
1863 {
1864 nni_aio_schedule(aio, fn, arg);
1865 }
1866
1867 bool
nng_aio_begin(nng_aio * aio)1868 nng_aio_begin(nng_aio *aio)
1869 {
1870 if (nni_aio_begin(aio) != 0) {
1871 return (false);
1872 }
1873 return (true);
1874 }
1875
1876 int
nng_url_parse(nng_url ** result,const char * ustr)1877 nng_url_parse(nng_url **result, const char *ustr)
1878 {
1879 return (nni_url_parse(result, ustr));
1880 }
1881
1882 void
nng_url_free(nng_url * url)1883 nng_url_free(nng_url *url)
1884 {
1885 nni_url_free(url);
1886 }
1887
1888 int
nng_url_clone(nng_url ** dstp,const nng_url * src)1889 nng_url_clone(nng_url **dstp, const nng_url *src)
1890 {
1891 return (nni_url_clone(dstp, src));
1892 }
1893
1894 #define xstr(a) str(a)
1895 #define str(a) #a
1896
1897 const char *
nng_version(void)1898 nng_version(void)
1899 {
1900 return (xstr(NNG_MAJOR_VERSION) "." xstr(NNG_MINOR_VERSION) "." xstr(
1901 NNG_PATCH_VERSION) NNG_RELEASE_SUFFIX);
1902 }
1903