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