aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/man/CMakeLists.txt726
-rw-r--r--docs/man/libnng.3.adoc4
-rw-r--r--docs/man/nng_stat.5.adoc4
-rw-r--r--docs/man/nng_stat_find.adoc52
-rw-r--r--docs/man/nng_stat_find_dialer.adoc56
-rw-r--r--docs/man/nng_stat_find_listener.adoc56
-rw-r--r--docs/man/nng_stat_find_socket.adoc56
-rw-r--r--include/nng/nng.h24
-rw-r--r--src/core/stats.c80
-rw-r--r--src/core/stats.h3
-rw-r--r--src/protocol/reqrep0/reqrep_test.c32
-rw-r--r--src/supplemental/util/platform.c1
-rw-r--r--tests/testutil.c57
-rw-r--r--tests/testutil.h5
14 files changed, 762 insertions, 394 deletions
diff --git a/docs/man/CMakeLists.txt b/docs/man/CMakeLists.txt
index ad397314..f357d60a 100644
--- a/docs/man/CMakeLists.txt
+++ b/docs/man/CMakeLists.txt
@@ -9,417 +9,421 @@
# found online at https://opensource.org/licenses/MIT.
# We default to off here.
-option (NNG_ENABLE_DOC "Enable building documentation." OFF)
+option(NNG_ENABLE_DOC "Enable building documentation." OFF)
if (NNG_ENABLE_DOC)
- find_program (ASCIIDOCTOR asciidoctor)
+ find_program(ASCIIDOCTOR asciidoctor)
if (NOT ASCIIDOCTOR)
- message (WARNING "Could not find asciidoctor: skipping docs")
- set (NNG_ENABLE_DOC OFF)
+ message(WARNING "Could not find asciidoctor: skipping docs")
+ set(NNG_ENABLE_DOC OFF)
else ()
- message (STATUS "Using asciidoctor at ${ASCIIDOCTOR}")
+ message(STATUS "Using asciidoctor at ${ASCIIDOCTOR}")
endif ()
endif ()
if (NNG_ENABLE_DOC)
- set (NNG_DOCDIR ${CMAKE_CURRENT_SOURCE_DIR})
+ set(NNG_DOCDIR ${CMAKE_CURRENT_SOURCE_DIR})
- set (NNG_A2M ${ASCIIDOCTOR} -b manpage -amanmanual='NNG Reference Manual')
- set (NNG_A2H ${ASCIIDOCTOR} -a nofooter -atoc=left -aicons=font -d manpage -b html5)
+ set(NNG_A2M ${ASCIIDOCTOR} -b manpage -amanmanual='NNG Reference Manual')
+ set(NNG_A2H ${ASCIIDOCTOR} -a nofooter -atoc=left -aicons=font -d manpage -b html5)
- macro (nng_man NAME SECT)
+ macro(nng_man NAME SECT)
- add_custom_command (
- OUTPUT ${NAME}.${SECT}
- COMMAND ${NNG_A2M} -o ${NAME}.${SECT} ${NNG_DOCDIR}/${NAME}.${SECT}.adoc
- MAIN_DEPENDENCY ${NNG_DOCDIR}/${NAME}.${SECT}.adoc
- )
+ add_custom_command(
+ OUTPUT ${NAME}.${SECT}
+ COMMAND ${NNG_A2M} -o ${NAME}.${SECT} ${NNG_DOCDIR}/${NAME}.${SECT}.adoc
+ MAIN_DEPENDENCY ${NNG_DOCDIR}/${NAME}.${SECT}.adoc
+ )
- add_custom_command (
- OUTPUT ${NAME}.${SECT}.html
- COMMAND ${NNG_A2H} -o ${NAME}.${SECT}.html ${NNG_DOCDIR}/${NAME}.${SECT}.adoc
- MAIN_DEPENDENCY ${NNG_DOCDIR}/${NAME}.${SECT}.adoc
- )
+ add_custom_command(
+ OUTPUT ${NAME}.${SECT}.html
+ COMMAND ${NNG_A2H} -o ${NAME}.${SECT}.html ${NNG_DOCDIR}/${NAME}.${SECT}.adoc
+ MAIN_DEPENDENCY ${NNG_DOCDIR}/${NAME}.${SECT}.adoc
+ )
- set(NNG_MANS ${NNG_MANS} ${NAME}.${SECT})
- set(NNG_HTMLS ${NNG_HTMLS} ${NAME}.${SECT}.html)
+ set(NNG_MANS ${NNG_MANS} ${NAME}.${SECT})
+ set(NNG_HTMLS ${NNG_HTMLS} ${NAME}.${SECT}.html)
- install (
- FILES ${CMAKE_CURRENT_BINARY_DIR}/${NAME}.${SECT}.html
- DESTINATION ${CMAKE_INSTALL_DOCDIR}
- )
- install (
- FILES ${CMAKE_CURRENT_BINARY_DIR}/${NAME}.${SECT}
- DESTINATION ${CMAKE_INSTALL_MANDIR}/man${SECT}
- )
+ install(
+ FILES ${CMAKE_CURRENT_BINARY_DIR}/${NAME}.${SECT}.html
+ DESTINATION ${CMAKE_INSTALL_DOCDIR}
+ )
+ install(
+ FILES ${CMAKE_CURRENT_BINARY_DIR}/${NAME}.${SECT}
+ DESTINATION ${CMAKE_INSTALL_MANDIR}/man${SECT}
+ )
- endmacro (nng_man)
+ endmacro(nng_man)
- set (NNG_MAN1
- nngcat
- )
+ set(NNG_MAN1
+ nngcat
+ )
- set (NNG_MAN3
- libnng
- nng_aio_abort
- nng_aio_alloc
- nng_aio_begin
- nng_aio_cancel
- nng_aio_count
- nng_aio_defer
- nng_aio_finish
- nng_aio_free
- nng_aio_get_input
- nng_aio_get_msg
- nng_aio_get_output
- nng_aio_result
- nng_aio_set_input
- nng_aio_set_iov
- nng_aio_set_msg
- nng_aio_set_output
- nng_aio_set_timeout
- nng_aio_stop
- nng_aio_wait
- nng_alloc
- nng_bus_open
- nng_close
- nng_ctx_close
- nng_ctx_get
- nng_ctx_getopt
- nng_ctx_id
- nng_ctx_open
- nng_ctx_recv
- nng_ctx_send
- nng_ctx_set
- nng_ctx_setopt
- nng_device
- nng_dial
- nng_dialer_close
- nng_dialer_create
- nng_dialer_get
- nng_dialer_getopt
- nng_dialer_id
- nng_dialer_set
- nng_dialer_setopt
- nng_dialer_start
- nng_free
- nng_getopt
- nng_inproc_register
- nng_ipc_register
- nng_listen
- nng_listener_close
- nng_listener_create
- nng_listener_get
- nng_listener_getopt
- nng_listener_id
- nng_listener_set
- nng_listener_setopt
- nng_listener_start
- nng_msg_alloc
- nng_msg_append
- nng_msg_body
- nng_msg_chop
- nng_msg_clear
- nng_msg_dup
- nng_msg_free
- nng_msg_get_pipe
- nng_msg_header
- nng_msg_header_append
- nng_msg_header_chop
- nng_msg_header_clear
- nng_msg_header_insert
- nng_msg_header_len
- nng_msg_header_trim
- nng_msg_insert
- nng_msg_len
- nng_msg_realloc
- nng_msg_set_pipe
- nng_msg_trim
- nng_pair_open
- nng_pipe_close
- nng_pipe_dialer
- nng_pipe_get
- nng_pipe_getopt
- nng_pipe_id
- nng_pipe_listener
- nng_pipe_notify
- nng_pipe_socket
- nng_pub_open
- nng_pull_open
- nng_push_open
- nng_recv
- nng_recv_aio
- nng_recvmsg
- nng_rep_open
- nng_req_open
- nng_respondent_open
- nng_send
- nng_send_aio
- nng_sendmsg
- nng_setopt
- nng_sleep_aio
- nng_socket_id
- nng_socket_get
- nng_socket_set
- nng_stats_free
- nng_stats_get
- nng_stat_child
- nng_stat_desc
- nng_stat_name
- nng_stat_next
- nng_stat_string
- nng_stat_timestamp
- nng_stat_type
- nng_stat_unit
- nng_stat_value
- nng_strdup
- nng_strerror
- nng_strfree
- nng_sub_open
- nng_surveyor_open
- nng_tcp_register
- nng_tls_register
- nng_url_clone
- nng_url_free
- nng_url_parse
- nng_version
- nng_ws_register
- nng_wss_register
- nng_zt_register
- )
+ set(NNG_MAN3
+ libnng
+ nng_aio_abort
+ nng_aio_alloc
+ nng_aio_begin
+ nng_aio_cancel
+ nng_aio_count
+ nng_aio_defer
+ nng_aio_finish
+ nng_aio_free
+ nng_aio_get_input
+ nng_aio_get_msg
+ nng_aio_get_output
+ nng_aio_result
+ nng_aio_set_input
+ nng_aio_set_iov
+ nng_aio_set_msg
+ nng_aio_set_output
+ nng_aio_set_timeout
+ nng_aio_stop
+ nng_aio_wait
+ nng_alloc
+ nng_bus_open
+ nng_close
+ nng_ctx_close
+ nng_ctx_get
+ nng_ctx_getopt
+ nng_ctx_id
+ nng_ctx_open
+ nng_ctx_recv
+ nng_ctx_send
+ nng_ctx_set
+ nng_ctx_setopt
+ nng_device
+ nng_dial
+ nng_dialer_close
+ nng_dialer_create
+ nng_dialer_get
+ nng_dialer_getopt
+ nng_dialer_id
+ nng_dialer_set
+ nng_dialer_setopt
+ nng_dialer_start
+ nng_free
+ nng_getopt
+ nng_inproc_register
+ nng_ipc_register
+ nng_listen
+ nng_listener_close
+ nng_listener_create
+ nng_listener_get
+ nng_listener_getopt
+ nng_listener_id
+ nng_listener_set
+ nng_listener_setopt
+ nng_listener_start
+ nng_msg_alloc
+ nng_msg_append
+ nng_msg_body
+ nng_msg_chop
+ nng_msg_clear
+ nng_msg_dup
+ nng_msg_free
+ nng_msg_get_pipe
+ nng_msg_header
+ nng_msg_header_append
+ nng_msg_header_chop
+ nng_msg_header_clear
+ nng_msg_header_insert
+ nng_msg_header_len
+ nng_msg_header_trim
+ nng_msg_insert
+ nng_msg_len
+ nng_msg_realloc
+ nng_msg_set_pipe
+ nng_msg_trim
+ nng_pair_open
+ nng_pipe_close
+ nng_pipe_dialer
+ nng_pipe_get
+ nng_pipe_getopt
+ nng_pipe_id
+ nng_pipe_listener
+ nng_pipe_notify
+ nng_pipe_socket
+ nng_pub_open
+ nng_pull_open
+ nng_push_open
+ nng_recv
+ nng_recv_aio
+ nng_recvmsg
+ nng_rep_open
+ nng_req_open
+ nng_respondent_open
+ nng_send
+ nng_send_aio
+ nng_sendmsg
+ nng_setopt
+ nng_sleep_aio
+ nng_socket_id
+ nng_socket_get
+ nng_socket_set
+ nng_stats_free
+ nng_stats_get
+ nng_stat_child
+ nng_stat_desc
+ nng_stat_find
+ nng_stat_find_dialer
+ nng_stat_find_listener
+ nng_stat_find_socket
+ nng_stat_name
+ nng_stat_next
+ nng_stat_string
+ nng_stat_timestamp
+ nng_stat_type
+ nng_stat_unit
+ nng_stat_value
+ nng_strdup
+ nng_strerror
+ nng_strfree
+ nng_sub_open
+ nng_surveyor_open
+ nng_tcp_register
+ nng_tls_register
+ nng_url_clone
+ nng_url_free
+ nng_url_parse
+ nng_version
+ nng_ws_register
+ nng_wss_register
+ nng_zt_register
+ )
set(NNG_MAN3COMPAT
- nn_allocmsg
- nn_bind
- nn_close
- nn_cmsg
- nn_connect
- nn_device
- nn_errno
- nn_freemsg
- nn_get_statistic
- nn_getsockopt
- nn_poll
- nn_reallocmsg
- nn_recv
- nn_recvmsg
- nn_send
- nn_sendmsg
- nn_setsockopt
- nn_shutdown
- nn_socket
- nn_strerror
- nn_term
- nng_compat
- )
+ nn_allocmsg
+ nn_bind
+ nn_close
+ nn_cmsg
+ nn_connect
+ nn_device
+ nn_errno
+ nn_freemsg
+ nn_get_statistic
+ nn_getsockopt
+ nn_poll
+ nn_reallocmsg
+ nn_recv
+ nn_recvmsg
+ nn_send
+ nn_sendmsg
+ nn_setsockopt
+ nn_shutdown
+ nn_socket
+ nn_strerror
+ nn_term
+ nng_compat
+ )
set(NNG_MAN3HTTP
- nng_http_client_alloc
- nng_http_client_connect
- nng_http_client_free
- nng_http_client_get_tls
- nng_http_client_set_tls
- nng_http_client_transact
- nng_http_conn_close
- nng_http_conn_read
- nng_http_conn_read_all
- nng_http_conn_read_req
- nng_http_conn_read_res
- nng_http_conn_transact
- nng_http_conn_write
- nng_http_conn_write_all
- nng_http_conn_write_req
- nng_http_conn_write_res
- nng_http_handler_alloc
- nng_http_handler_free
- nng_http_handler_get_data
- nng_http_handler_set_data
- nng_http_handler_set_host
- nng_http_handler_set_method
- nng_http_handler_set_tree
- nng_http_hijack
- nng_http_req_add_header
- nng_http_req_alloc
- nng_http_req_copy_data
- nng_http_req_del_header
- nng_http_req_free
- nng_http_req_get_data
- nng_http_req_get_header
- nng_http_req_get_method
- nng_http_req_get_uri
- nng_http_req_get_version
- nng_http_req_reset
- nng_http_req_set_data
- nng_http_req_set_header
- nng_http_req_set_method
- nng_http_req_set_uri
- nng_http_req_set_version
- nng_http_res_add_header
- nng_http_res_alloc
- nng_http_res_alloc_error
- nng_http_res_copy_data
- nng_http_res_del_header
- nng_http_res_free
- nng_http_res_get_data
- nng_http_res_get_header
- nng_http_res_get_reason
- nng_http_res_get_status
- nng_http_res_get_version
- nng_http_res_reset
- nng_http_res_set_data
- nng_http_res_set_header
- nng_http_res_set_reason
- nng_http_res_set_status
- nng_http_res_set_version
- nng_http_server_add_handler
- nng_http_server_del_handler
- nng_http_server_get_addr
- nng_http_server_get_tls
- nng_http_server_hold
- nng_http_server_release
- nng_http_server_set_tls
- nng_http_server_start
- nng_http_server_stop
- )
+ nng_http_client_alloc
+ nng_http_client_connect
+ nng_http_client_free
+ nng_http_client_get_tls
+ nng_http_client_set_tls
+ nng_http_client_transact
+ nng_http_conn_close
+ nng_http_conn_read
+ nng_http_conn_read_all
+ nng_http_conn_read_req
+ nng_http_conn_read_res
+ nng_http_conn_transact
+ nng_http_conn_write
+ nng_http_conn_write_all
+ nng_http_conn_write_req
+ nng_http_conn_write_res
+ nng_http_handler_alloc
+ nng_http_handler_free
+ nng_http_handler_get_data
+ nng_http_handler_set_data
+ nng_http_handler_set_host
+ nng_http_handler_set_method
+ nng_http_handler_set_tree
+ nng_http_hijack
+ nng_http_req_add_header
+ nng_http_req_alloc
+ nng_http_req_copy_data
+ nng_http_req_del_header
+ nng_http_req_free
+ nng_http_req_get_data
+ nng_http_req_get_header
+ nng_http_req_get_method
+ nng_http_req_get_uri
+ nng_http_req_get_version
+ nng_http_req_reset
+ nng_http_req_set_data
+ nng_http_req_set_header
+ nng_http_req_set_method
+ nng_http_req_set_uri
+ nng_http_req_set_version
+ nng_http_res_add_header
+ nng_http_res_alloc
+ nng_http_res_alloc_error
+ nng_http_res_copy_data
+ nng_http_res_del_header
+ nng_http_res_free
+ nng_http_res_get_data
+ nng_http_res_get_header
+ nng_http_res_get_reason
+ nng_http_res_get_status
+ nng_http_res_get_version
+ nng_http_res_reset
+ nng_http_res_set_data
+ nng_http_res_set_header
+ nng_http_res_set_reason
+ nng_http_res_set_status
+ nng_http_res_set_version
+ nng_http_server_add_handler
+ nng_http_server_del_handler
+ nng_http_server_get_addr
+ nng_http_server_get_tls
+ nng_http_server_hold
+ nng_http_server_release
+ nng_http_server_set_tls
+ nng_http_server_start
+ nng_http_server_stop
+ )
set(NNG_MAN3SUPP
- nng_clock
- nng_cv_alloc
- nng_cv_free
- nng_cv_until
- nng_cv_wait
- nng_cv_wake
- nng_cv_wake1
- nng_msleep
- nng_mtx_alloc
- nng_mtx_free
- nng_mtx_lock
- nng_mtx_unlock
- nng_opts_parse
- nng_random
- nng_thread_create
- nng_thread_destroy
- )
+ nng_clock
+ nng_cv_alloc
+ nng_cv_free
+ nng_cv_until
+ nng_cv_wait
+ nng_cv_wake
+ nng_cv_wake1
+ nng_msleep
+ nng_mtx_alloc
+ nng_mtx_free
+ nng_mtx_lock
+ nng_mtx_unlock
+ nng_opts_parse
+ nng_random
+ nng_thread_create
+ nng_thread_destroy
+ )
set(NNG_MAN3STR
- nng_stream_close
- nng_stream_free
- nng_stream_get
- nng_stream_recv
- nng_stream_send
- nng_stream_set
- nng_stream_dialer_alloc
- nng_stream_dialer_close
- nng_stream_dialer_dial
- nng_stream_dialer_free
- nng_stream_dialer_get
- nng_stream_dialer_set
- nng_stream_listener_accept
- nng_stream_listener_alloc
- nng_stream_listener_close
- nng_stream_listener_free
- nng_stream_listener_get
- nng_stream_listener_listen
- nng_stream_listener_set
- )
+ nng_stream_close
+ nng_stream_free
+ nng_stream_get
+ nng_stream_recv
+ nng_stream_send
+ nng_stream_set
+ nng_stream_dialer_alloc
+ nng_stream_dialer_close
+ nng_stream_dialer_dial
+ nng_stream_dialer_free
+ nng_stream_dialer_get
+ nng_stream_dialer_set
+ nng_stream_listener_accept
+ nng_stream_listener_alloc
+ nng_stream_listener_close
+ nng_stream_listener_free
+ nng_stream_listener_get
+ nng_stream_listener_listen
+ nng_stream_listener_set
+ )
set(NNG_MAN3TLS
- nng_tls_config_alloc
- nng_tls_config_auth_mode
- nng_tls_config_ca_chain
- nng_tls_config_ca_file
- nng_tls_config_cert_key_file
- nng_tls_config_free
- nng_tls_config_hold
- nng_tls_config_own_cert
- nng_tls_config_server_name
- )
+ nng_tls_config_alloc
+ nng_tls_config_auth_mode
+ nng_tls_config_ca_chain
+ nng_tls_config_ca_file
+ nng_tls_config_cert_key_file
+ nng_tls_config_free
+ nng_tls_config_hold
+ nng_tls_config_own_cert
+ nng_tls_config_server_name
+ )
set(NNG_MAN5
- nng_aio
- nng_ctx
- nng_dialer
- nng_duration
- nng_iov
- nng_listener
- nng_msg
- nng_options
- nng_pipe
- nng_sockaddr
- nng_sockaddr_in
- nng_sockaddr_in6
- nng_sockaddr_inproc
- nng_sockaddr_ipc
- nng_sockaddr_zt
- nng_socket
- nng_stat
+ nng_aio
+ nng_ctx
+ nng_dialer
+ nng_duration
+ nng_iov
+ nng_listener
+ nng_msg
+ nng_options
+ nng_pipe
+ nng_sockaddr
+ nng_sockaddr_in
+ nng_sockaddr_in6
+ nng_sockaddr_inproc
+ nng_sockaddr_ipc
+ nng_sockaddr_zt
+ nng_socket
+ nng_stat
- nng_stream
- nng_stream_dialer
- nng_stream_listener
+ nng_stream
+ nng_stream_dialer
+ nng_stream_listener
- nng_tcp_options
- nng_ipc_options
- nng_tls_config
- nng_tls_options
- )
+ nng_tcp_options
+ nng_ipc_options
+ nng_tls_config
+ nng_tls_options
+ )
set(NNG_MAN7
- nng
- nng_bus
- nng_inproc
- nng_ipc
- nng_pair
- nng_pub
- nng_pull
- nng_push
- nng_rep
- nng_req
- nng_respondent
- nng_sub
- nng_surveyor
- nng_tcp
- nng_tls
- nng_ws
- nng_zerotier
- )
+ nng
+ nng_bus
+ nng_inproc
+ nng_ipc
+ nng_pair
+ nng_pub
+ nng_pull
+ nng_push
+ nng_rep
+ nng_req
+ nng_respondent
+ nng_sub
+ nng_surveyor
+ nng_tcp
+ nng_tls
+ nng_ws
+ nng_zerotier
+ )
- foreach(F ${NNG_MAN1})
+ foreach (F ${NNG_MAN1})
nng_man(${F} 1)
- endforeach()
+ endforeach ()
- foreach(F ${NNG_MAN3})
+ foreach (F ${NNG_MAN3})
nng_man(${F} 3)
- endforeach()
+ endforeach ()
- foreach(F ${NNG_MAN3COMPAT})
+ foreach (F ${NNG_MAN3COMPAT})
nng_man(${F} 3compat)
- endforeach()
+ endforeach ()
- foreach(F ${NNG_MAN3HTTP})
+ foreach (F ${NNG_MAN3HTTP})
nng_man(${F} 3http)
- endforeach()
+ endforeach ()
- foreach(F ${NNG_MAN3STR})
+ foreach (F ${NNG_MAN3STR})
nng_man(${F} 3str)
- endforeach()
+ endforeach ()
- foreach(F ${NNG_MAN3SUPP})
+ foreach (F ${NNG_MAN3SUPP})
nng_man(${F} 3supp)
- endforeach()
+ endforeach ()
- foreach(F ${NNG_MAN3TLS})
+ foreach (F ${NNG_MAN3TLS})
nng_man(${F} 3tls)
- endforeach()
+ endforeach ()
- foreach(F ${NNG_MAN5})
+ foreach (F ${NNG_MAN5})
nng_man(${F} 5)
- endforeach()
+ endforeach ()
- foreach(F ${NNG_MAN7})
+ foreach (F ${NNG_MAN7})
nng_man(${F} 7)
- endforeach()
+ endforeach ()
- add_custom_target (man ALL DEPENDS ${NNG_MANS})
- add_custom_target (html ALL DEPENDS ${NNG_HTMLS})
+ add_custom_target(man ALL DEPENDS ${NNG_MANS})
+ add_custom_target(html ALL DEPENDS ${NNG_HTMLS})
endif ()
diff --git a/docs/man/libnng.3.adoc b/docs/man/libnng.3.adoc
index 35c9b0f4..4e59890f 100644
--- a/docs/man/libnng.3.adoc
+++ b/docs/man/libnng.3.adoc
@@ -240,6 +240,10 @@ to observe program behaviors and as an aid in troubleshooting.
|===
|xref:nng_stat_child.3.adoc[nng_stat_child()]|get child statistic
|xref:nng_stat_desc.3.adoc[nng_stat_name()]|get statistic description
+|xref:nng_stat_find.3.adoc[nng_stat_find()]|find statistic by name
+|xref:nng_stat_find_dialer.3.adoc[nng_stat_find_dialer()]|find dialer statistics
+|xref:nng_stat_find_listener.3.adoc[nng_stat_find_listener()]|find listener statistics
+|xref:nng_stat_find_socket.3.adoc[nng_stat_find_socket()]|find socket statistics
|xref:nng_stat_name.3.adoc[nng_stat_name()]|get statistic name
|xref:nng_stat_next.3.adoc[nng_stat_next()]|get next statistic
|xref:nng_stat_string.3.adoc[nng_stat_string()]|get statistic string value
diff --git a/docs/man/nng_stat.5.adoc b/docs/man/nng_stat.5.adoc
index 4382e4b0..0b649308 100644
--- a/docs/man/nng_stat.5.adoc
+++ b/docs/man/nng_stat.5.adoc
@@ -68,6 +68,10 @@ xref:nng_stats_free.3.adoc[nng_stats_free(3)],
xref:nng_stats_get.3.adoc[nng_stats_get(3)],
xref:nng_stat_child.3.adoc[nng_stat_child(3)],
xref:nng_stat_desc.3.adoc[nng_stat_desc(3)],
+xref:nng_stat_find.3.adoc[nng_stat_find(3)],
+xref:nng_stat_find_dialer.3.adoc[nng_stat_find_dialer(3)],
+xref:nng_stat_find_listener.3.adoc[nng_stat_find_listener(3)],
+xref:nng_stat_find_socket.3.adoc[nng_stat_find_socket(3)],
xref:nng_stat_name.3.adoc[nng_stat_name(3)],
xref:nng_stat_next.3.adoc[nng_stat_next(3)],
xref:nng_stat_string.3.adoc[nng_stat_string(3)],
diff --git a/docs/man/nng_stat_find.adoc b/docs/man/nng_stat_find.adoc
new file mode 100644
index 00000000..4f4103ea
--- /dev/null
+++ b/docs/man/nng_stat_find.adoc
@@ -0,0 +1,52 @@
+= nng_stat_find(3)
+//
+// Copyright 2019 Staysail Systems, Inc. <info@staysail.tech>
+//
+// This document is supplied under the terms of the MIT License, a
+// copy of which should be located in the distribution where this
+// file was obtained (LICENSE.txt). A copy of the license may also be
+// found online at https://opensource.org/licenses/MIT.
+//
+
+== NAME
+
+nng_stat_find - find statistic by name
+
+== SYNOPSIS
+
+[source,c]
+----
+#include <nng/nng.h>
+
+typedef struct nng_stat nng_stat;
+
+nng_stat *nng_stat_find(nng_stat *stat, const char *name);
+----
+
+== DESCRIPTION
+
+The `nng_stat_find()` function searches the statistics tree _stat_, looking for a statistic whose name is _name_.
+If it finds one, it returns it.
+Otherwise `NULL` is returned.
+
+NOTE: If multiple statistics have that name, then only the first match is returned.
+
+== RETURN VALUES
+
+The matching statistic, or NULL if no match is found.
+
+== ERRORS
+
+None.
+
+== SEE ALSO
+
+[.text-left]
+xref:libnng.3.adoc[libnng(3)],
+xref:nng_stat_child.3.adoc[nng_stat_child(3)],
+xref:nng_stat_find_dialer.3.adoc[nng_stat_find_dialer(3)],
+xref:nng_stat_find_listener.3.adoc[nng_stat_find_listner(3)],
+xref:nng_stat_find_socket.3.adoc[nng_stat_find_socket(3)],
+xref:nng_stats_get.3.adoc[nng_stats_get(3)],
+xref:nng_stat.5.adoc[nng_stat(5)],
+xref:nng.7.adoc[nng(7)]
diff --git a/docs/man/nng_stat_find_dialer.adoc b/docs/man/nng_stat_find_dialer.adoc
new file mode 100644
index 00000000..b0df247a
--- /dev/null
+++ b/docs/man/nng_stat_find_dialer.adoc
@@ -0,0 +1,56 @@
+= nng_stat_find_socket(3)
+//
+// Copyright 2019 Staysail Systems, Inc. <info@staysail.tech>
+//
+// This document is supplied under the terms of the MIT License, a
+// copy of which should be located in the distribution where this
+// file was obtained (LICENSE.txt). A copy of the license may also be
+// found online at https://opensource.org/licenses/MIT.
+//
+
+== NAME
+
+nng_stat_find_dialer - find dialer statistics
+
+== SYNOPSIS
+
+[source,c]
+----
+#include <nng/nng.h>
+
+typedef struct nng_stat nng_stat;
+typedef struct nng_dialer nng_dialer;
+
+nng_stat *nng_stat_find_dialer(nng_stat *stat, nng_dialer dialer);
+----
+
+== DESCRIPTION
+
+The `nng_stat_find_dialer()` function returns the statistics tree within _stat_ associated with the dialer _dialer_, if such a tree exists.
+Otherwise `NULL` is returned.
+
+Generally, there will be child statistics of the returned value, each corresponding to a specific metric.
+These can be further scanned using either
+xref:nng_stat_find.3.adoc[nng_stat_find(3)]
+or by walking the tree with
+xref:nng_stat_child.3.adoc[nng_stat_child(3)].
+
+== RETURN VALUES
+
+The matching statistic, or NULL if no match is found.
+
+== ERRORS
+
+None.
+
+== SEE ALSO
+
+[.text-left]
+xref:libnng.3.adoc[libnng(3)],
+xref:nng_stat_child.3.adoc[nng_stat_child(3)],
+xref:nng_stat_find.3.adoc[nng_stat_find(3)],
+xref:nng_stat_find_listener.3.adoc[nng_stat_find_listener(3)],
+xref:nng_stat_find_socket.3.adoc[nng_stat_find_socket(3)],
+xref:nng_stats_get.3.adoc[nng_stats_get(3)],
+xref:nng_stat.5.adoc[nng_stat(5)],
+xref:nng.7.adoc[nng(7)]
diff --git a/docs/man/nng_stat_find_listener.adoc b/docs/man/nng_stat_find_listener.adoc
new file mode 100644
index 00000000..2a099b1b
--- /dev/null
+++ b/docs/man/nng_stat_find_listener.adoc
@@ -0,0 +1,56 @@
+= nng_stat_find_listener(3)
+//
+// Copyright 2019 Staysail Systems, Inc. <info@staysail.tech>
+//
+// This document is supplied under the terms of the MIT License, a
+// copy of which should be located in the distribution where this
+// file was obtained (LICENSE.txt). A copy of the license may also be
+// found online at https://opensource.org/licenses/MIT.
+//
+
+== NAME
+
+nng_stat_find_listener - find listener statistics
+
+== SYNOPSIS
+
+[source,c]
+----
+#include <nng/nng.h>
+
+typedef struct nng_stat nng_stat;
+typedef struct nng_listener nng_listener;
+
+nng_stat *nng_stat_find_listener(nng_stat *stat, nng_listener listener);
+----
+
+== DESCRIPTION
+
+The `nng_stat_find_listener()` function returns the statistics tree within _stat_ associated with the listener _listener_, if such a tree exists.
+Otherwise `NULL` is returned.
+
+Generally, there will be child statistics of the returned value, each corresponding to a specific metric.
+These can be further scanned using either
+xref:nng_stat_find.3.adoc[nng_stat_find(3)]
+or by walking the tree with
+xref:nng_stat_child.3.adoc[nng_stat_child(3)].
+
+== RETURN VALUES
+
+The matching statistic, or NULL if no match is found.
+
+== ERRORS
+
+None.
+
+== SEE ALSO
+
+[.text-left]
+xref:libnng.3.adoc[libnng(3)],
+xref:nng_stat_child.3.adoc[nng_stat_child(3)],
+xref:nng_stat_find.3.adoc[nng_stat_find(3)],
+xref:nng_stat_find_dialer.3.adoc[nng_stat_find_dialer(3)],
+xref:nng_stat_find_socket.3.adoc[nng_stat_find_socket(3)],
+xref:nng_stats_get.3.adoc[nng_stats_get(3)],
+xref:nng_stat.5.adoc[nng_stat(5)],
+xref:nng.7.adoc[nng(7)]
diff --git a/docs/man/nng_stat_find_socket.adoc b/docs/man/nng_stat_find_socket.adoc
new file mode 100644
index 00000000..eb03d5ea
--- /dev/null
+++ b/docs/man/nng_stat_find_socket.adoc
@@ -0,0 +1,56 @@
+= nng_stat_find_socket(3)
+//
+// Copyright 2019 Staysail Systems, Inc. <info@staysail.tech>
+//
+// This document is supplied under the terms of the MIT License, a
+// copy of which should be located in the distribution where this
+// file was obtained (LICENSE.txt). A copy of the license may also be
+// found online at https://opensource.org/licenses/MIT.
+//
+
+== NAME
+
+nng_stat_find_socket - find socket statistics
+
+== SYNOPSIS
+
+[source,c]
+----
+#include <nng/nng.h>
+
+typedef struct nng_stat nng_stat;
+typedef struct nng_socket nng_socket;
+
+nng_stat *nng_stat_find_socket(nng_stat *stat, nng_socket socket);
+----
+
+== DESCRIPTION
+
+The `nng_stat_find_socket()` function returns the statistics tree within _stat_ associated with the socket _socket_, if such a tree exists.
+Otherwise `NULL` is returned.
+
+Generally, there will be child statistics of the returned value, each corresponding to a specific metric.
+These can be further scanned using either
+xref:nng_stat_find.3.adoc[nng_stat_find(3)]
+or by walking the tree with
+xref:nng_stat_child.3.adoc[nng_stat_child(3)].
+
+== RETURN VALUES
+
+The matching statistic, or NULL if no match is found.
+
+== ERRORS
+
+None.
+
+== SEE ALSO
+
+[.text-left]
+xref:libnng.3.adoc[libnng(3)],
+xref:nng_stat_child.3.adoc[nng_stat_child(3)],
+xref:nng_stat_find.3.adoc[nng_stat_find(3)],
+xref:nng_stat_find_dialer.3.adoc[nng_stat_find_dialer(3)],
+xref:nng_stat_find_listener.3.adoc[nng_stat_find_listener(3)],
+xref:nng_stats_get.3.adoc[nng_stats_get(3)],
+xref:nng_stat.5.adoc[nng_stat(5)],
+xref:nng.7.adoc[nng(7)]
diff --git a/include/nng/nng.h b/include/nng/nng.h
index 0db81ef5..2c9dd8c3 100644
--- a/include/nng/nng.h
+++ b/include/nng/nng.h
@@ -915,7 +915,7 @@ enum nng_flag_enum {
// This can be useful when a handler supports an entire directory tree.
#define NNG_OPT_WS_REQUEST_URI "ws:request-uri"
-// NNG_OPT_WS_TXFRAMESZ is used to configure the fragmentation size
+// NNG_OPT_WS_SENDMAXFRAME is used to configure the fragmentation size
// used for frames. This has a default value of 64k. Large values
// are good for throughput, but penalize latency. They also require
// additional buffering on the peer. This value must not be larger
@@ -923,7 +923,7 @@ enum nng_flag_enum {
// to negotiate this.
#define NNG_OPT_WS_SENDMAXFRAME "ws:txframe-max"
-// NNG_OPT_WS_RXFRAMESZ is the largest frame we will accept. This should
+// NNG_OPT_WS_RECVMAXFRAME is the largest frame we will accept. This should
// probably not be larger than NNG_OPT_RECVMAXSZ. If the sender attempts
// to send more data than this in a single message, it will be dropped.
#define NNG_OPT_WS_RECVMAXFRAME "ws:rxframe-max"
@@ -943,7 +943,7 @@ enum nng_flag_enum {
// nng_stats_get takes a snapshot of the entire set of statistics.
// While the operation can be somewhat expensive (allocations), it
// is done in a way that minimizes impact to running operations.
-// Note that the statistics are provided as tree, with parents
+// Note that the statistics are provided as a tree, with parents
// used for grouping, and with child statistics underneath. The
// top stat returned will be of type NNG_STAT_SCOPE with name "".
// Applications may choose to consider this root scope as "root", if
@@ -973,13 +973,25 @@ NNG_DECL nng_stat *nng_stat_child(nng_stat *);
NNG_DECL const char *nng_stat_name(nng_stat *);
// nng_stat_type is used to determine the type of the statistic.
-// At present, only NNG_STAT_TYPE_LEVEL and and NNG_STAT_TYPE_COUNTER
-// are defined. Counters generally increment, and therefore changes in the
-// value over time are likely more interesting than the actual level. Level
+// Counters generally increment, and therefore changes in the value over
+// time are likely more interesting than the actual level. Level
// values reflect some absolute state however, and should be presented to the
// user as is.
NNG_DECL int nng_stat_type(nng_stat *);
+// nng_stat_find is used to find a specific named statistic within
+// a statistic tree. NULL is returned if no such statistic exists.
+NNG_DECL nng_stat *nng_stat_find(nng_stat *, const char *);
+
+// nng_stat_find_socket is used to find the stats for the given socket.
+NNG_DECL nng_stat *nng_stat_find_socket(nng_stat *, nng_socket);
+
+// nng_stat_find_dialer is used to find the stats for the given dialer.
+NNG_DECL nng_stat *nng_stat_find_dialer(nng_stat *, nng_dialer);
+
+// nng_stat_find_listener is used to find the stats for the given listener.
+NNG_DECL nng_stat *nng_stat_find_listener(nng_stat *, nng_listener);
+
enum nng_stat_type_enum {
NNG_STAT_SCOPE = 0, // Stat is for scoping, and carries no value
NNG_STAT_LEVEL = 1, // Numeric "absolute" value, diffs meaningless
diff --git a/src/core/stats.c b/src/core/stats.c
index 3c200fec..d526014a 100644
--- a/src/core/stats.c
+++ b/src/core/stats.c
@@ -17,8 +17,8 @@ typedef struct nng_stat nni_stat;
struct nng_stat {
char * s_name;
- const char * s_desc;
- const char * s_string;
+ char * s_desc;
+ char * s_string;
uint64_t s_value;
nni_time s_time;
nni_stat_type s_type;
@@ -182,17 +182,6 @@ nni_stat_set_value(nni_stat_item *stat, uint64_t v)
}
void
-nni_stat_set_string(nni_stat_item *stat, const char *str)
-{
-#ifdef NNG_ENABLE_STATS
- stat->si_string = str;
-#else
- NNI_ARG_UNUSED(stat);
- NNI_ARG_UNUSED(str);
-#endif
-}
-
-void
nni_stat_set_lock(nni_stat_item *stat, nni_mtx *mtx)
{
#ifdef NNG_ENABLE_STATS
@@ -241,6 +230,8 @@ nng_stats_free(nni_stat *st)
nng_stats_free(child);
}
nni_strfree(st->s_name);
+ nni_strfree(st->s_desc);
+ nni_strfree(st->s_string);
NNI_FREE_STRUCT(st);
#else
NNI_ARG_UNUSED(st);
@@ -257,15 +248,21 @@ stat_make_tree(nni_stat_item *item, nni_stat **sp)
if ((stat = NNI_ALLOC_STRUCT(stat)) == NULL) {
return (NNG_ENOMEM);
}
- if ((stat->s_name = nni_strdup(item->si_name)) == NULL) {
- NNI_FREE_STRUCT(stat);
+ NNI_LIST_INIT(&stat->s_children, nni_stat, s_node);
+
+ if (((stat->s_name = nni_strdup(item->si_name)) == NULL) ||
+ ((stat->s_desc = nni_strdup(item->si_desc)) == NULL)) {
+ nng_stats_free(stat);
+ return (NNG_ENOMEM);
+ }
+ if ((item->si_type == NNG_STAT_STRING) &&
+ ((stat->s_string = nni_strdup(item->si_string)) == NULL)) {
+ nng_stats_free(stat);
return (NNG_ENOMEM);
}
- NNI_LIST_INIT(&stat->s_children, nni_stat, s_node);
stat->s_item = item;
stat->s_type = item->si_type;
stat->s_unit = item->si_unit;
- stat->s_desc = item->si_desc;
stat->s_parent = NULL;
NNI_LIST_FOREACH (&item->si_children, child) {
@@ -300,9 +297,8 @@ stat_update(nni_stat *stat)
if (item->si_update != NULL) {
item->si_update(item, item->si_private);
}
- stat->s_value = item->si_number;
- stat->s_string = item->si_string;
- stat->s_time = nni_clock();
+ stat->s_value = item->si_number;
+ stat->s_time = nni_clock();
}
static void
@@ -418,6 +414,49 @@ nng_stat_desc(nng_stat *stat)
return (stat->s_desc);
}
+nng_stat *
+nng_stat_find(nng_stat *stat, const char *name)
+{
+ nng_stat *child;
+ nng_stat *result;
+ if (stat == NULL) {
+ return (NULL);
+ }
+ if (strcmp(name, stat->s_name) == 0) {
+ return (stat);
+ }
+ NNI_LIST_FOREACH(&stat->s_children, child) {
+ if ((result = nng_stat_find(child, name)) != NULL) {
+ return (result);
+ }
+ }
+ return (NULL);
+}
+
+nng_stat *
+nng_stat_find_socket(nng_stat *stat, nng_socket s)
+{
+ char name[16];
+ (void) snprintf(name, sizeof (name), "socket%d", nng_socket_id(s));
+ return (nng_stat_find(stat, name));
+}
+
+nng_stat *
+nng_stat_find_dialer(nng_stat *stat, nng_dialer d)
+{
+ char name[16];
+ (void) snprintf(name, sizeof (name), "dialer%d", nng_dialer_id(d));
+ return (nng_stat_find(stat, name));
+}
+
+nng_stat *
+nng_stat_find_listener(nng_stat *stat, nng_listener l)
+{
+ char name[16];
+ (void) snprintf(name, sizeof (name), "listener%d", nng_listener_id(l));
+ return (nng_stat_find(stat, name));
+}
+
int
nni_stat_sys_init(void)
{
@@ -427,7 +466,6 @@ nni_stat_sys_init(void)
stats_root.si_name = "";
stats_root.si_desc = "all statistics";
#endif
-
return (0);
}
diff --git a/src/core/stats.h b/src/core/stats.h
index 12dbbbdd..a9ea6e13 100644
--- a/src/core/stats.h
+++ b/src/core/stats.h
@@ -1,5 +1,5 @@
//
-// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
+// Copyright 2019 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
//
// This software is supplied under the terms of the MIT License, a
@@ -66,7 +66,6 @@ void nni_stat_register(nni_stat_item *);
void nni_stat_unregister(nni_stat_item *);
void nni_stat_set_value(nni_stat_item *, uint64_t);
-void nni_stat_set_string(nni_stat_item *, const char *);
void nni_stat_set_lock(nni_stat_item *, nni_mtx *);
void nni_stat_set_update(nni_stat_item *, nni_stat_update, void *);
diff --git a/src/protocol/reqrep0/reqrep_test.c b/src/protocol/reqrep0/reqrep_test.c
index b68c08cb..f4617936 100644
--- a/src/protocol/reqrep0/reqrep_test.c
+++ b/src/protocol/reqrep0/reqrep_test.c
@@ -387,6 +387,37 @@ test_req_context_not_pollable(void)
TEST_NNG_PASS(nng_close(req));
}
+void
+test_req_validate_peer(void)
+{
+ nng_socket s1, s2;
+ nng_stat * stats;
+ nng_stat * reject;
+ char addr[64];
+
+ testutil_scratch_addr("inproc", sizeof(addr), addr);
+
+ TEST_NNG_PASS(nng_req0_open(&s1));
+ TEST_NNG_PASS(nng_req0_open(&s2));
+
+ TEST_NNG_PASS(nng_listen(s1, addr, NULL, 0));
+ TEST_NNG_PASS(nng_dial(s2, addr, NULL, NNG_FLAG_NONBLOCK));
+
+ testutil_sleep(100);
+ TEST_NNG_PASS(nng_stats_get(&stats));
+
+ TEST_CHECK(stats != NULL);
+ TEST_CHECK((reject = nng_stat_find_socket(stats, s1)) != NULL);
+ TEST_CHECK((reject = nng_stat_find(reject, "reject")) != NULL);
+
+ TEST_CHECK(nng_stat_type(reject) == NNG_STAT_COUNTER);
+ TEST_CHECK(nng_stat_value(reject) > 0);
+
+ TEST_NNG_PASS(nng_close(s1));
+ TEST_NNG_PASS(nng_close(s2));
+ nng_stats_free(stats);
+}
+
TEST_LIST = {
{ "req rep identity", test_req_rep_identity },
{ "resend option", test_resend_option },
@@ -398,5 +429,6 @@ TEST_LIST = {
{ "req poll writable", test_req_poll_writeable },
{ "req poll readable", test_req_poll_readable },
{ "req context not pollable", test_req_context_not_pollable },
+ { "req validate peer", test_req_validate_peer },
{ NULL, NULL },
};
diff --git a/src/supplemental/util/platform.c b/src/supplemental/util/platform.c
index 138e8b0b..468582bd 100644
--- a/src/supplemental/util/platform.c
+++ b/src/supplemental/util/platform.c
@@ -155,5 +155,6 @@ nng_cv_wake1(nng_cv *cv)
uint32_t
nng_random(void)
{
+ (void) nni_init();
return (nni_random());
}
diff --git a/tests/testutil.c b/tests/testutil.c
index 1c65c996..36999448 100644
--- a/tests/testutil.c
+++ b/tests/testutil.c
@@ -127,14 +127,63 @@ uint32_t
testutil_htonl(uint32_t in)
{
#ifdef NNG_LITTLE_ENDIAN
- in = ((in >> 24u) & 0xffu) |
- ((in >> 8u) & 0xff00u) |
- ((in << 8u) & 0xff0000u) |
- ((in << 24u) & 0xff000000u);
+ in = ((in >> 24u) & 0xffu) | ((in >> 8u) & 0xff00u) |
+ ((in << 8u) & 0xff0000u) | ((in << 24u) & 0xff000000u);
#endif
return (in);
}
+void
+testutil_scratch_addr(const char *scheme, size_t sz, char *addr)
+{
+ if (strcmp(scheme, "inproc") == 0) {
+ (void) snprintf(addr, sz, "%s://testutil%04x%04x%04x%04x",
+ scheme, nng_random(), nng_random(), nng_random(),
+ nng_random());
+ return;
+ }
+
+ if ((strncmp(scheme, "tcp", 3) == 0) ||
+ (strncmp(scheme, "tls", 3) == 0)) {
+ (void) snprintf(addr, sz, "%s://127.0.0.1:%u", scheme,
+ testutil_next_port());
+ return;
+ }
+
+ if (strncmp(scheme, "ws", 2) == 0) {
+ (void) snprintf(addr, sz,
+ "%s://127.0.0.1:%u/testutil%04x%04x%04x%04x", scheme,
+ testutil_next_port(), nng_random(), nng_random(),
+ nng_random(), nng_random());
+ return;
+ }
+
+ if (strncmp(scheme, "ipc", 3) == 0) {
+#ifdef _WIN32
+ // Windows doesn't place IPC names in the filesystem.
+ (void) snprintf(addr, sz, "%s://testutil%04x%04x%04x%04x",
+ scheme, nng_random(), nng_random(), nng_random(),
+ nng_random());
+#else
+ char *tmpdir;
+
+ if (((tmpdir = getenv("TMPDIR")) == NULL) &&
+ ((tmpdir = getenv("TEMP")) == NULL) &&
+ ((tmpdir = getenv("TMP")) == NULL)) {
+ tmpdir = "/tmp";
+ }
+
+ (void) snprintf(addr, sz, "%s://%s/testutil%04x%04x%04x%04x",
+ scheme, tmpdir, nng_random(), nng_random(), nng_random(),
+ nng_random());
+ return;
+#endif
+ }
+
+ // We should not be here.
+ abort();
+}
+
// testutil_next_port returns a "next" allocation port.
// Ports are chosen by starting from a random point within a
// range (normally 38000-40000, but other good places to choose
diff --git a/tests/testutil.h b/tests/testutil.h
index b9acfedf..14cc1712 100644
--- a/tests/testutil.h
+++ b/tests/testutil.h
@@ -40,6 +40,11 @@ extern void testutil_sleep(int);
// testutil_next_port returns a new port number (presumably unique)
extern uint16_t testutil_next_port(void);
+// testutil_scratch_addr makes a scratch address for the given scheme.
+// The address buffer must be supplied, and the size should be at least
+// 64 bytes to ensure no truncation occurs.
+extern void testutil_scratch_addr(const char *, size_t, char *);
+
// testutil_marry connects two sockets using inproc. It uses socket
// pipe hooks to ensure that it does not return before both sockets
// are fully connected.