add nng-v1.5.2
This commit is contained in:
commit
c49214afb8
736 changed files with 123659 additions and 0 deletions
14
external/nng/.clang-format
vendored
Normal file
14
external/nng/.clang-format
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
BasedOnStyle: WebKit
|
||||
UseTab: ForIndentation
|
||||
IndentWidth: 8
|
||||
ColumnLimit: 79
|
||||
AlignConsecutiveAssignments: true
|
||||
AlignConsecutiveDeclarations: true
|
||||
AlignTrailingComments: true
|
||||
AlignEscapedNewlinesLeft: true
|
||||
PointerAlignment: Right
|
||||
ForEachMacros: ['NNI_LIST_FOREACH']
|
||||
AlwaysBreakAfterReturnType: TopLevelDefinitions
|
||||
SpaceAfterCStyleCast: true
|
||||
AllowShortFunctionsOnASingleLine: Inline
|
||||
BreakBeforeBinaryOperators: None
|
7
external/nng/.codecov.yml
vendored
Normal file
7
external/nng/.codecov.yml
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
ignore:
|
||||
- "tests"
|
||||
- "src/testing"
|
||||
- "perf"
|
||||
- "**/*_test.c"
|
||||
coverage:
|
||||
range: 50..95
|
2
external/nng/.gitattributes
vendored
Normal file
2
external/nng/.gitattributes
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
*.sh text eol=lf
|
||||
|
5
external/nng/.github/FUNDING.yml
vendored
Normal file
5
external/nng/.github/FUNDING.yml
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
# These are supported funding model platforms
|
||||
github: gdamore
|
||||
patreon: gedamore
|
||||
custom: [ "https://staysail.tech/support/" ]
|
||||
custom: [ "https://leanpub.com/nngref2e" ]
|
30
external/nng/.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
30
external/nng/.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Actual Behavior**
|
||||
Describe what occurred.
|
||||
|
||||
**To Reproduce**
|
||||
If possible include actual reproduction test code here.
|
||||
Minimal C test cases are perferred.
|
||||
|
||||
** Environment Details **
|
||||
- NNG version
|
||||
- Operating system and version
|
||||
- Compiler and language used
|
||||
- Shared or static library
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
20
external/nng/.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
20
external/nng/.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
7
external/nng/.github/pull_request_template.md
vendored
Normal file
7
external/nng/.github/pull_request_template.md
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
fixes #<issue number> <issue synopsis>
|
||||
|
||||
<Comments describing your change. Not all changes need this.>
|
||||
|
||||
Note that the above format should be used in your git commit comments.
|
||||
You agree that by submitting a PR, you have read and agreed to our
|
||||
contributing guidelines.
|
72
external/nng/.github/workflows/codeql-analysis.yml
vendored
Normal file
72
external/nng/.github/workflows/codeql-analysis.yml
vendored
Normal file
|
@ -0,0 +1,72 @@
|
|||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
#
|
||||
# ******** NOTE ********
|
||||
# We have attempted to detect the languages in your repository. Please check
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ master ]
|
||||
schedule:
|
||||
- cron: '27 2 * * 2'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'cpp' ]
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
|
||||
# Learn more:
|
||||
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
queries: +security-and-quality
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v1
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
|
||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||
# and modify them (or add more) to build your code if your project
|
||||
# uses a compiled language
|
||||
|
||||
#- run: |
|
||||
# make bootstrap
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
65
external/nng/.github/workflows/coverage.yml
vendored
Normal file
65
external/nng/.github/workflows/coverage.yml
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
name: coverage
|
||||
on: [push]
|
||||
jobs:
|
||||
|
||||
linux-coverage:
|
||||
name: linux
|
||||
runs-on: [ ubuntu-latest ]
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v1
|
||||
|
||||
- name: Install mbedTLS
|
||||
run: sudo apt-get install libmbedtls-dev
|
||||
|
||||
- name: Install ninja
|
||||
run: sudo apt-get install ninja-build
|
||||
|
||||
- name: Configure
|
||||
run: mkdir build && cd build && cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -DNNG_ENABLE_COVERAGE=ON -DNNG_ENABLE_TLS=ON ..
|
||||
|
||||
- name: build
|
||||
run: cd build && ninja
|
||||
|
||||
- name: Test
|
||||
run: cd build && ctest --output-on-failure
|
||||
|
||||
- name: Upload report
|
||||
uses: codecov/codecov-action@v1
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
yml: ./.codecov.yml
|
||||
|
||||
darwin-coverage:
|
||||
name: darwin
|
||||
runs-on: [ macos-latest ]
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v1
|
||||
|
||||
- name: Install mbedTLS
|
||||
run: brew install mbedtls
|
||||
|
||||
- name: Install ninja
|
||||
run: brew install ninja
|
||||
|
||||
- name: Install lcov
|
||||
run: brew install lcov
|
||||
|
||||
- name: Configure
|
||||
run: mkdir build && cd build && cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -DNNG_ENABLE_COVERAGE=ON -DNNG_ENABLE_TLS=ON ..
|
||||
|
||||
- name: build
|
||||
run: cd build && ninja
|
||||
|
||||
- name: Test
|
||||
run: cd build && ctest --output-on-failure
|
||||
|
||||
- name: Preprocess
|
||||
run: cd build && lcov -c -d . -o lcov.info
|
||||
|
||||
- name: Upload report
|
||||
uses: codecov/codecov-action@v1
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
yml: ./.codecov.yml
|
22
external/nng/.github/workflows/darwin.yml
vendored
Normal file
22
external/nng/.github/workflows/darwin.yml
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
name: darwin
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
|
||||
build:
|
||||
name: build
|
||||
runs-on: [ macos-latest ]
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v1
|
||||
|
||||
- name: Install ninja
|
||||
run: brew install ninja
|
||||
|
||||
- name: Configure
|
||||
run: mkdir build && cd build && cmake -G Ninja ..
|
||||
|
||||
- name: build
|
||||
run: cd build && ninja
|
||||
|
||||
- name: Test
|
||||
run: cd build && ctest --output-on-failure
|
25
external/nng/.github/workflows/linux.yml
vendored
Normal file
25
external/nng/.github/workflows/linux.yml
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
name: linux
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
|
||||
build:
|
||||
name: build
|
||||
runs-on: [ ubuntu-latest ]
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v1
|
||||
|
||||
- name: Install mbedTLS
|
||||
run: sudo apt-get install libmbedtls-dev
|
||||
|
||||
- name: Install ninja
|
||||
run: sudo apt-get install ninja-build
|
||||
|
||||
- name: Configure
|
||||
run: mkdir build && cd build && cmake -G Ninja -D NNG_ENABLE_TLS=ON ..
|
||||
|
||||
- name: Build
|
||||
run: cd build && ninja
|
||||
|
||||
- name: Test
|
||||
run: cd build && ctest --output-on-failure
|
35
external/nng/.github/workflows/sanitizer.yml
vendored
Normal file
35
external/nng/.github/workflows/sanitizer.yml
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
name: sanitize
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
sanitize:
|
||||
env:
|
||||
CC: clang
|
||||
CXX: clang++
|
||||
CTEST_OUTPUT_ON_FAILURE: 1
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
sanitizer: [ address, undefined, thread ]
|
||||
os: [ ubuntu-latest ]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
|
||||
- uses: mstksg/get-package@v1
|
||||
with:
|
||||
apt-get: ninja-build libmbedtls-dev
|
||||
brew: ninja mbedtls
|
||||
|
||||
- name: Configure
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -G Ninja -DNNG_SANITIZER=${{ matrix.sanitizer }} -DCMAKE_BUILD_TYPE=Debug -DNNG_ENABLE_TLS=ON -DNNG_TOOLS=OFF ..
|
||||
- name: Build
|
||||
run: |
|
||||
cd build
|
||||
ninja
|
||||
- name: Test
|
||||
run: |
|
||||
cd build
|
||||
ninja test
|
22
external/nng/.github/workflows/windows.yml
vendored
Normal file
22
external/nng/.github/workflows/windows.yml
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
name: windows
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
|
||||
build:
|
||||
name: build
|
||||
runs-on: [ windows-latest ]
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v1
|
||||
|
||||
- name: Configure
|
||||
run: cmake -B build
|
||||
|
||||
- name: Build
|
||||
run: cmake --build build
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
cd build
|
||||
ctest -C Debug --output-on-failure
|
||||
|
12
external/nng/.gitignore
vendored
Normal file
12
external/nng/.gitignore
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
build
|
||||
lxbuild
|
||||
winbuild
|
||||
wbuild
|
||||
.vs
|
||||
.vscode/.cmaketools.json
|
||||
.vscode
|
||||
.idea
|
||||
.DS_Store
|
||||
etc/nng.sublime-workspace
|
||||
cmake-build-*
|
||||
docs/**/*.html
|
3
external/nng/.gitmodules
vendored
Normal file
3
external/nng/.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
[submodule "extern/nng-wolfssl"]
|
||||
path = extern/nng-wolfssl
|
||||
url = https://github.com/staysail/nng-wolfssl
|
5
external/nng/.grcov.yml
vendored
Normal file
5
external/nng/.grcov.yml
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
branch: true
|
||||
ignore-not-existing: true
|
||||
filter: covered
|
||||
output-type: lcov
|
||||
output-file: lcov.info
|
276
external/nng/CMakeLists.txt
vendored
Normal file
276
external/nng/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,276 @@
|
|||
#
|
||||
# Copyright 2021 Staysail Systems, Inc. <info@staysail.tech>
|
||||
# Copyright (c) 2012 Martin Sustrik All rights reserved.
|
||||
# Copyright (c) 2013 GoPivotal, Inc. All rights reserved.
|
||||
# Copyright (c) 2015-2016 Jack R. Dunaway. All rights reserved.
|
||||
# Copyright 2016 Franklin "Snaipe" Mathieu <franklinmathieu@gmail.com>
|
||||
# Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom
|
||||
# the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
# IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
project(nng C)
|
||||
include(CheckCCompilerFlag)
|
||||
include(GNUInstallDirs)
|
||||
|
||||
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
|
||||
|
||||
include(NNGHelpers)
|
||||
include(NNGOptions)
|
||||
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}" isSystemDir)
|
||||
if ("${isSystemDir}" STREQUAL "-1")
|
||||
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
|
||||
endif ("${isSystemDir}" STREQUAL "-1")
|
||||
|
||||
set(NNG_DESCRIPTION "High-Performance Scalability Protocols NextGen")
|
||||
set(ISSUE_REPORT_MSG "Please consider opening an issue at https://github.com/nanomsg/nng")
|
||||
|
||||
# Determine library versions.
|
||||
file(READ "include/nng/nng.h" nng_ver_h)
|
||||
string(REGEX MATCH "NNG_MAJOR_VERSION ([0-9]*)" _ ${nng_ver_h})
|
||||
set(NNG_MAJOR_VERSION ${CMAKE_MATCH_1})
|
||||
string(REGEX MATCH "NNG_MINOR_VERSION ([0-9]*)" _ ${nng_ver_h})
|
||||
set(NNG_MINOR_VERSION ${CMAKE_MATCH_1})
|
||||
string(REGEX MATCH "NNG_PATCH_VERSION ([0-9]*)" _ ${nng_ver_h})
|
||||
set(NNG_PATCH_VERSION ${CMAKE_MATCH_1})
|
||||
string(REGEX MATCH "NNG_RELEASE_SUFFIX \"([a-z0-9]*)\"" _ ${nng_ver_h})
|
||||
if (NOT ("${CMAKE_MATCH_1}" STREQUAL ""))
|
||||
set(NNG_PRERELEASE "-${CMAKE_MATCH_1}")
|
||||
endif ()
|
||||
|
||||
set(NNG_ABI_SOVERSION 1)
|
||||
set(NNG_ABI_VERSION "${NNG_MAJOR_VERSION}.${NNG_MINOR_VERSION}.${NNG_PATCH_VERSION}${NNG_PRERELEASE}")
|
||||
set(NNG_PACKAGE_VERSION "${NNG_ABI_VERSION}")
|
||||
message(STATUS "Configuring for NNG version ${NNG_ABI_VERSION}")
|
||||
|
||||
# User-defined options.
|
||||
|
||||
# This prefix is appended to by subdirectories, so that each test
|
||||
# gets named based on where it is in the tree.
|
||||
set(NNG_TEST_PREFIX nng)
|
||||
|
||||
# Enable access to private APIs for our own use.
|
||||
add_definitions(-DNNG_PRIVATE)
|
||||
|
||||
if (NOT (BUILD_SHARED_LIBS))
|
||||
set(NNG_STATIC_LIB ON)
|
||||
message(STATUS "Building static libs.")
|
||||
endif ()
|
||||
|
||||
# These are library targets. The "nng" library is the main public library.
|
||||
# The "nng_testing" is a full build of the library for test cases
|
||||
# only, which is done statically and includes even portions of the code
|
||||
# that are not part of the public library (things that may have been elided.)
|
||||
# The "nng_private" library is an interface that allows some internal tools
|
||||
# to obtain details about how the public library was built, so that we can
|
||||
# include or not include code based on what's actually present.
|
||||
add_library(nng)
|
||||
|
||||
add_library(nng_testing STATIC EXCLUDE_FROM_ALL)
|
||||
target_compile_definitions(nng_testing PUBLIC NNG_STATIC_LIB NNG_TEST_LIB NNG_PRIVATE)
|
||||
|
||||
add_library(nng_private INTERFACE)
|
||||
target_compile_definitions(nng_private INTERFACE NNG_PRIVATE)
|
||||
|
||||
if (NNG_ELIDE_DEPRECATED)
|
||||
target_compile_definitions(nng PRIVATE NNG_ELIDE_DEPRECATED)
|
||||
endif()
|
||||
|
||||
|
||||
# We can use rlimit to configure the stack size for systems
|
||||
# that have too small defaults. This is not used for Windows,
|
||||
# which can grow thread stacks sensibly. (Note that NNG can get
|
||||
# by with a smallish stack, but application callbacks might require
|
||||
# larger values if using aio completion callbacks. TLS libraries may
|
||||
# require larger stacks however.)
|
||||
if (NOT WIN32)
|
||||
option(NNG_SETSTACKSIZE "Use rlimit for thread stack size" OFF)
|
||||
if (NNG_SETSTACKSIZE)
|
||||
add_definitions(-DNNG_SETSTACKSIZE)
|
||||
endif ()
|
||||
mark_as_advanced(NNG_SETSTACKSIZE)
|
||||
endif ()
|
||||
|
||||
nng_defines_if(NNG_ENABLE_STATS NNG_ENABLE_STATS)
|
||||
|
||||
if (NNG_RESOLV_CONCURRENCY)
|
||||
add_definitions(-DNNG_RESOLV_CONCURRENCY=${NNG_RESOLV_CONCURRENCY})
|
||||
endif ()
|
||||
mark_as_advanced(NNG_RESOLV_CONCURRENCY)
|
||||
|
||||
if (NNG_NUM_TASKQ_THREADS)
|
||||
add_definitions(-DNNG_NUM_TASKQ_THREADS=${NNG_NUM_TASKQ_THREADS})
|
||||
endif ()
|
||||
mark_as_advanced(NNG_NUM_TASKQ_THREADS)
|
||||
|
||||
set(NNG_MAX_TASKQ_THREADS 16 CACHE STRING "Upper bound on taskq threads, 0 for no limit")
|
||||
mark_as_advanced(NNG_MAX_TASKQ_THREADS)
|
||||
if (NNG_MAX_TASKQ_THREADS)
|
||||
add_definitions(-DNNG_MAX_TASKQ_THREADS=${NNG_MAX_TASKQ_THREADS})
|
||||
endif ()
|
||||
|
||||
# Platform checks.
|
||||
|
||||
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||
set(NNG_WARN_FLAGS "-Wall -Wextra -fno-omit-frame-pointer")
|
||||
elseif (CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
set(NNG_WARN_FLAGS "-Wall -Wextra -fno-omit-frame-pointer")
|
||||
endif ()
|
||||
|
||||
include(CheckSanitizer)
|
||||
CheckSanitizer()
|
||||
if (NOT NNG_SANITIZER STREQUAL "none")
|
||||
set(NNG_SANITIZER_FLAGS "-fsanitize=${NNG_SANITIZER}")
|
||||
endif ()
|
||||
|
||||
if (NNG_ENABLE_COVERAGE)
|
||||
# NB: This only works for GCC and Clang 3.0 and newer. If your stuff
|
||||
# is older than that, you will need to find something newer. For
|
||||
# correct reporting, we always turn off all optimizations.
|
||||
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||
set(NNG_COVERAGE_C_FLAGS "-g -O0 --coverage")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS --coverage)
|
||||
elseif (CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
set(NNG_COVERAGE_C_FLAGS "-g -O0 --coverage")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS --coverage)
|
||||
else ()
|
||||
message(FATAL_ERROR "Unable to enable coverage for your compiler.")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${NNG_WARN_FLAGS} ${NNG_COVERAGE_C_FLAGS} ${NNG_SANITIZER_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${NNG_WARN_FLAGS} ${NNG_COVERAGE_C_FLAGS} ${NNG_SANITIZER_FLAGS}")
|
||||
|
||||
# If the compiler is not on Windows, does it support hiding the
|
||||
# symbols by default? For shared libraries we would like to do this.
|
||||
if (NOT WIN32 AND NOT CYGWIN)
|
||||
check_c_compiler_flag(-fvisibility=hidden NNG_HIDDEN_VISIBILITY)
|
||||
if (NNG_HIDDEN_VISIBILITY)
|
||||
add_definitions(-DNNG_HIDDEN_VISIBILITY)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
add_definitions(-DNNG_PLATFORM_POSIX)
|
||||
add_definitions(-DNNG_PLATFORM_LINUX)
|
||||
add_definitions(-DNNG_USE_EVENTFD)
|
||||
add_definitions(-DNNG_HAVE_ABSTRACT_SOCKETS)
|
||||
# Windows subsystem for Linux -- smells like Linux, but it has
|
||||
# some differences (SO_REUSEADDR for one).
|
||||
if (CMAKE_SYSTEM_VERSION MATCHES "Microsoft")
|
||||
add_definitions(-DNNG_PLATFORM_WSL)
|
||||
endif ()
|
||||
set(NNG_PLATFORM_POSIX ON)
|
||||
|
||||
elseif (CMAKE_SYSTEM_NAME MATCHES "Android")
|
||||
add_definitions(-DNNG_PLATFORM_POSIX)
|
||||
add_definitions(-DNNG_PLATFORM_LINUX)
|
||||
add_definitions(-DNNG_PLATFORM_ANDROID)
|
||||
add_definitions(-DNNG_USE_EVENTFD)
|
||||
set(NNG_PLATFORM_POSIX ON)
|
||||
|
||||
elseif (APPLE)
|
||||
add_definitions(-DNNG_PLATFORM_POSIX)
|
||||
add_definitions(-DNNG_PLATFORM_DARWIN)
|
||||
set(NNG_PLATFORM_POSIX ON)
|
||||
|
||||
elseif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
|
||||
add_definitions(-DNNG_PLATFORM_POSIX)
|
||||
add_definitions(-DNNG_PLATFORM_FREEBSD)
|
||||
set(NNG_PLATFORM_POSIX ON)
|
||||
|
||||
elseif (CMAKE_SYSTEM_NAME MATCHES "NetBSD")
|
||||
add_definitions(-DNNG_PLATFORM_POSIX)
|
||||
add_definitions(-DNNG_PLATFORM_NETBSD)
|
||||
set(NNG_PLATFORM_POSIX ON)
|
||||
|
||||
elseif (CMAKE_SYSTEM_NAME MATCHES "OpenBSD")
|
||||
add_definitions(-DNNG_PLATFORM_POSIX)
|
||||
add_definitions(-DNNG_PLATFORM_OPENBSD)
|
||||
set(NNG_PLATFORM_POSIX ON)
|
||||
|
||||
elseif (CMAKE_SYSTEM_NAME MATCHES "SunOS")
|
||||
add_definitions(-DNNG_PLATFORM_POSIX)
|
||||
add_definitions(-DNNG_PLATFORM_SUNOS)
|
||||
set(NNG_PLATFORM_POSIX ON)
|
||||
|
||||
elseif (CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||
add_definitions(-DNNG_PLATFORM_WINDOWS)
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||
add_definitions(-D_CRT_RAND_S)
|
||||
set(NNG_PLATFORM_WINDOWS ON)
|
||||
|
||||
# Target Windows Vista and later
|
||||
add_definitions(-D_WIN32_WINNT=0x0600)
|
||||
list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_WIN32_WINNT=0x0600)
|
||||
|
||||
elseif (CMAKE_SYSTEM_NAME MATCHES "QNX")
|
||||
add_definitions(-DNNG_PLATFORM_POSIX)
|
||||
add_definitions(-D__EXT_BSD)
|
||||
add_definitions(-D_QNX_SOURCE)
|
||||
add_definitions(-DNNG_PLATFORM_QNX)
|
||||
set(NNG_PLATFORM_POSIX ON)
|
||||
|
||||
else ()
|
||||
message(AUTHOR_WARNING "WARNING: This platform may not be supported: ${CMAKE_SYSTEM_NAME}")
|
||||
message(AUTHOR_WARNING "${ISSUE_REPORT_MSG}")
|
||||
# blithely hope for POSIX to work
|
||||
add_definitions(-DNNG_PLATFORM_POSIX)
|
||||
set(NNG_PLATFORM_POSIX ON)
|
||||
endif ()
|
||||
|
||||
if (NNG_ENABLE_TLS)
|
||||
add_definitions(-DNNG_SUPP_TLS)
|
||||
endif ()
|
||||
|
||||
if (NNG_TESTS)
|
||||
enable_testing()
|
||||
set(all_tests, "")
|
||||
endif ()
|
||||
|
||||
add_subdirectory(src)
|
||||
|
||||
if (NNG_TESTS)
|
||||
add_subdirectory(tests)
|
||||
endif ()
|
||||
|
||||
# Build the tools
|
||||
|
||||
add_subdirectory(docs/man)
|
||||
|
||||
set(CPACK_PACKAGE_NAME ${PROJECT_NAME})
|
||||
set(CPACK_PACKAGE_VERSION ${NNG_PACKAGE_VERSION})
|
||||
set(CPACK_PACKAGE_CONTACT "nanomsg@freelists.org")
|
||||
set(CPACK_PACKAGE_VENDOR "nanomsg.org")
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "nanomsg next generation library")
|
||||
set(CPACK_SOURCE_GENERATOR "TBZ2;TGZ;ZIP")
|
||||
set(CPACK_SOURCE_IGNORE_FILES "/build/;/.git/;~$;${CPACK_SOURCE_IGNORE_FILES}")
|
||||
set(CPACK_SOURCE_PACKAGE_FILE_NAME
|
||||
"${PROJECT_NAME}-v${NNG_PACKAGE_VERSION}-src")
|
||||
set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.txt)
|
||||
set(CPACK_PACKAGE_INSTALL_DIRECTORY "nng")
|
||||
set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-v${NNG_PACKAGE_VERSION}")
|
||||
|
||||
add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source)
|
||||
include(CPack)
|
74
external/nng/CODE_OF_CONDUCT.adoc
vendored
Normal file
74
external/nng/CODE_OF_CONDUCT.adoc
vendored
Normal file
|
@ -0,0 +1,74 @@
|
|||
= NNG Code of Conduct
|
||||
|
||||
== Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, gender identity and expression, level of
|
||||
experience,
|
||||
nationality, personal appearance, race, religion, or sexual identity and
|
||||
orientation.
|
||||
|
||||
== Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
== Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
== Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
|
||||
== Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at garrett@damore.org. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an
|
||||
incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
== Attribution
|
||||
|
||||
This Code of Conduct is adapted from the
|
||||
https://www.contributor-convent.org[Contributor Covenant], version 1.4,
|
||||
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
22
external/nng/LICENSE.txt
vendored
Normal file
22
external/nng/LICENSE.txt
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
The MIT License
|
||||
|
||||
Copyright 2021 Staysail Systems, Inc. <info@staysail.tech>
|
||||
Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom
|
||||
the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
IN THE SOFTWARE.
|
181
external/nng/README.adoc
vendored
Normal file
181
external/nng/README.adoc
vendored
Normal file
|
@ -0,0 +1,181 @@
|
|||
ifdef::env-github[]
|
||||
:note-caption: :information_source:
|
||||
:important-caption: :heavy_exclamation_mark:
|
||||
endif::[]
|
||||
= nng - nanomsg-next-gen
|
||||
|
||||
// Note: This README is optimized for display with Asciidoctor, or
|
||||
// on the github status page. An HTML version is in the same directory
|
||||
// and may be more pleasantly formatted for human readers (when opened
|
||||
// in a browser).
|
||||
|
||||
// Note: If you're updating this file, don't forget to re-run asciidoctor
|
||||
// to update the aforementioned HTML file!
|
||||
|
||||
image:https://img.shields.io/github/workflow/status/nanomsg/nng/linux/master?logoColor=grey&logo=ubuntu&label=[Linux Status,link="https://github.com/nanomsg/nng/actions"]
|
||||
image:https://img.shields.io/github/workflow/status/nanomsg/nng/windows/master?logoColor=grey&logo=windows&label=[Windows Status,link="https://github.com/nanomsg/nng/actions"]
|
||||
image:https://img.shields.io/github/workflow/status/nanomsg/nng/darwin/master?logoColor=grey&logo=apple&label=[macOS Status,link="https://github.com/nanomsg/nng/actions"]
|
||||
image:https://img.shields.io/codecov/c/github/nanomsg/nng?logo=codecov&logoColor=grey&label=[Coverage,link="https://codecov.io/gh/nanomsg/nng"]
|
||||
image:https://img.shields.io/lgtm/grade/cpp/github/nanomsg/nng?logo=lgtm&logoColor=grey&label=[LGTM,link="https://lgtm.com/projects/g/nanomsg/nng/?mode=list"]
|
||||
image:https://img.shields.io/discord/639573728212156478?label=&logo=discord[Discord,link="https://discord.gg/Xnac6b9"]
|
||||
image:https://img.shields.io/static/v1?label=&message=docs&logo=asciidoctor&logoColor=silver&color=blue[Manual,link="https://nng.nanomsg.org/man"]
|
||||
image:https://img.shields.io/github/license/nanomsg/nng.svg?logoColor=silver&logo=open-source-initiative&label=&color=blue[MIT License,link="https://github.com/nanomsg/nng/blob/master/LICENSE.txt"]
|
||||
image:https://img.shields.io/github/v/tag/nanomsg/nng.svg?logo=github&label=[Latest version,link="https://github.com/nanomsg/nng/releases"]
|
||||
|
||||
NOTE: If you are looking for the legacy version of nanomsg, please
|
||||
see the https://github.com/nanomsg/nanomsg[nanomsg] repository.
|
||||
|
||||
This project is a rewrite of the Scalability Protocols
|
||||
library known as https://github.com/nanomsg/nanomsg[libnanomsg],
|
||||
and adds significant new capabilities, while retaining
|
||||
compatibility with the original.
|
||||
|
||||
It may help to think of this as "nanomsg-next-generation".
|
||||
|
||||
== NNG: Lightweight Messaging Library
|
||||
|
||||
NNG, like its predecessors http://nanomsg.org[nanomsg] (and to some extent
|
||||
http://zeromq.org/[ZeroMQ]), is a lightweight, broker-less library,
|
||||
offering a simple API to solve common recurring messaging problems,
|
||||
such as publish/subscribe, RPC-style request/reply, or service discovery.
|
||||
The API frees the programmer from worrying about details like connection
|
||||
management, retries, and other common considerations, so that they
|
||||
can focus on the application instead of the plumbing.
|
||||
|
||||
NNG is implemented in C, requiring only C99 and CMake to build.
|
||||
It can be built as a shared or a static library, and is readily
|
||||
embeddable. It is also designed to be easy to port to new platforms
|
||||
if your platform is not already supported.
|
||||
|
||||
== License
|
||||
|
||||
NNG is licensed under a liberal, and commercial friendly, MIT license.
|
||||
The goal to the license is to minimize friction in adoption, use, and
|
||||
contribution.
|
||||
|
||||
== Enhancements (Relative to nanomsg)
|
||||
|
||||
Here are areas where this project improves on "nanomsg":
|
||||
|
||||
[horizontal]
|
||||
*Reliability*:: NNG is designed for production use from the beginning. Every
|
||||
error case is considered, and it is designed to avoid crashing except in cases
|
||||
of gross developer error. (Hopefully we don't have any of these in our own
|
||||
code.)
|
||||
|
||||
*Scalability*:: NNG scales out to engage multiple cores using a bespoke
|
||||
asynchronous I/O framework, using thread pools to spread load without
|
||||
exceeding typical system limits.
|
||||
|
||||
*Maintainability*:: NNG's architecture is designed to be modular and
|
||||
easily grasped by developers unfamiliar with the code base. The code
|
||||
is also well documented.
|
||||
|
||||
*Extensibility*:: Because it avoids ties to file descriptors, and avoids
|
||||
confusing interlocking state machines, it is easier to add new protocols
|
||||
and transports to NNG. This was demonstrated by the addition of the
|
||||
TLS and ZeroTier transports.
|
||||
|
||||
*Security*:: NNG provides TLS 1.2 and ZeroTier transports, offering
|
||||
support for robust and industry standard authentication and encryption.
|
||||
In addition, it is hardened to be resilient against malicious attackers,
|
||||
with special consideration given to use in a hostile Internet.
|
||||
|
||||
*Usability*:: NNG eschews slavish adherence parts of the more complex and
|
||||
less well understood POSIX APIs, while adopting the semantics that are
|
||||
familiar and useful. New APIs are intuitive, and the optional support
|
||||
for separating protocol context and state from sockets makes creating
|
||||
concurrent applications vastly simpler than previously possible.
|
||||
|
||||
== Compatibility
|
||||
|
||||
This project offers both wire compatibility and API compatibility,
|
||||
so most nanomsg users can begin using NNG right away.
|
||||
|
||||
Existing nanomsg and https://github.com/nanomsg/mangos[mangos] applications
|
||||
can inter-operate with NNG applications automatically.
|
||||
|
||||
That said, there are some areas where legacy nanomsg still offers
|
||||
capabilities NNG lacks -- specifically enhanced observability with
|
||||
statistics, and tunable prioritization of different destinations
|
||||
are missing, but will be added in a future release.
|
||||
|
||||
Additionally, some API capabilities that are useful for foreign
|
||||
language bindings are not implemented yet.
|
||||
|
||||
Some simple single threaded, synchronous applications may perform better under
|
||||
legacy nanomsg than under NNG. (We believe that these applications are the
|
||||
least commonly deployed, and least interesting from a performance perspective.
|
||||
NNG's internal design is slightly less efficient in such scenarios, but it
|
||||
greatly benefits when concurrency or when multiple sockets or network peers
|
||||
are involved.)
|
||||
|
||||
== Supported Platforms
|
||||
|
||||
NNG supports Linux, macOS, Windows (Vista or better), illumos, Solaris,
|
||||
FreeBSD, Android, and iOS. Most other POSIX platforms should work out of
|
||||
the box but have not been tested. Very old versions of otherwise supported
|
||||
platforms might not work.
|
||||
|
||||
== Requirements
|
||||
|
||||
To build this project, you will need a C99 compatible compiler and
|
||||
http://www.cmake.org[CMake] version 3.13 or newer.
|
||||
|
||||
We recommend using the https://ninja-build.org[Ninja] build
|
||||
system (pass "-G Ninja" to CMake) when you can.
|
||||
(And not just because Ninja sounds like "NNG" -- it's also
|
||||
blindingly fast and has made our lives as developers measurably better.)
|
||||
|
||||
If you want to build with TLS support you will also need
|
||||
https://tls.mbed.org[mbedTLS]. See <<docs/BUILD_TLS.adoc#>> for details.
|
||||
|
||||
== Quick Start
|
||||
|
||||
With a Linux or UNIX environment:
|
||||
|
||||
[source,sh]
|
||||
----
|
||||
$ mkdir build
|
||||
$ cd build
|
||||
$ cmake -G Ninja ..
|
||||
$ ninja
|
||||
$ ninja test
|
||||
$ ninja install
|
||||
----
|
||||
|
||||
== API Documentation
|
||||
|
||||
The API documentation is provided in Asciidoc format in the
|
||||
`docs/man` subdirectory, and also
|
||||
https://nanomsg.github.io/nng[online].
|
||||
The <<docs/man/libnng.3.adoc#,libnng(3)>> page is a good starting point.
|
||||
|
||||
You can also purchase a copy of the
|
||||
http://staysail.tech/books/nng_reference/index.html[__NNG Reference Manual__].
|
||||
(It is published in both electronic and printed formats.)
|
||||
Purchases of the book help fund continued development of NNG.
|
||||
|
||||
== Example Programs
|
||||
|
||||
Some demonstration programs have been created to help serve as examples.
|
||||
These are located in the `demo` directory.
|
||||
|
||||
== Legacy Compatibility
|
||||
|
||||
A legacy libnanomsg compatible API is available, and while it offers
|
||||
less capability than the modern NNG API, it may serve as a transition aid.
|
||||
Please see <<docs/man/nng_compat.3compat.adoc#,nng_compat(3)>> for details.
|
||||
|
||||
== Commercial Support
|
||||
|
||||
Commercial support for NNG is available.
|
||||
|
||||
Please contact mailto:info@staysail.tech[Staysail Systems, Inc.] to
|
||||
inquire further.
|
||||
|
||||
== Commercial Sponsors
|
||||
|
||||
The development of NNG has been made possible through the generous
|
||||
sponsorship of https://www.capitar.com[Capitar IT Group BV] and
|
||||
http://staysail.tech[Staysail Systems, Inc.].
|
67
external/nng/RELEASE_NOTES.adoc
vendored
Normal file
67
external/nng/RELEASE_NOTES.adoc
vendored
Normal file
|
@ -0,0 +1,67 @@
|
|||
= NNG Release Notes
|
||||
|
||||
== Release 1.3.0 (since 1.2.6)
|
||||
|
||||
=== Features
|
||||
|
||||
* Support for TLS 1.3 and external TLS providers.
|
||||
There is now an API whereby external "`engines`" can be developed
|
||||
for different TLS implementations. The first of these, for wolfSSL,
|
||||
is available. Set this with the `NNG_TLS_ENGINE` cmake option.
|
||||
The default is still to use Mbed TLS. The wolfSSL plugin is
|
||||
available under a different license (GPLv3 or commercial), and also
|
||||
provides support for TLS 1.3 and FIPS 140-2 capable solutions.
|
||||
|
||||
* Message cloning and related performance improvements. This is not
|
||||
a feature, so much as a rather large improvement in terms of performance.
|
||||
All workloads will see some benefit -- some will see substantial benefits.
|
||||
|
||||
* Numerous other performance improvements. Much effort was made to
|
||||
reducing allocations, improving cache effectiveness, and eliminating
|
||||
extra context switches. This work is not yet done, but this is a big
|
||||
step in the right direction.
|
||||
|
||||
* HTTP Server support for "non-exclusive" registration -- a given handler
|
||||
may be registered as a fallback handler (e.g. for a directory), even if
|
||||
more specific handlers are registered.
|
||||
|
||||
* Performance test programs grew more options to select different
|
||||
protocols and to change the URL to test across different transports.
|
||||
|
||||
=== Notable Bug Fixes
|
||||
|
||||
* Thread count is limited.
|
||||
Previously we would spawn potentially vast numbers of threads based on the
|
||||
number of available cores. By default we set an upper limit on this that
|
||||
is about 20 threads. Tune this with the `NNG_MAX_TASKQ_WORKERS` cmake option.
|
||||
|
||||
* Raw mode fixes for XREQ and XRESPONDENT. These protocols used the raw mode
|
||||
inconsistently, leaving the header in the message body. This is corrected
|
||||
and the protocol headers are kept in the message headers. There is some small
|
||||
risk that some applications broken, but we are not aware of any that used
|
||||
RAW mode to parse message headers.
|
||||
|
||||
* HTTP Server root URL handling had a few issues which are resolved.
|
||||
|
||||
* Some platforms had difficult building due to inconsistencies in the
|
||||
handling of atomics.
|
||||
|
||||
* Numerous test suites uncovered small (rare) races, etc. The tests
|
||||
themselves were often racy. Fixes to both NNG and the tests have been
|
||||
made, while increasing overall test coverage.
|
||||
|
||||
* REP protocol with SENDFD was inconsistent (#1088).
|
||||
|
||||
=== Other Changes
|
||||
|
||||
* Polyamorous Pair v1 mode is changed, such that a new API call is needed
|
||||
to use it. Further, this mode will likely be removed in a future release.
|
||||
Note that this mode also does not work with other implementations, nor
|
||||
does it support operation with `nng_device()`.
|
||||
|
||||
* Maximum hop count across `nng_device()` proxies is now limited to 15.
|
||||
This limit should be sufficient for all reasonable configurations,
|
||||
and forcing this allowed us to to inline the header for performance
|
||||
reasons.
|
||||
|
||||
* The nng_msg_options support was removed. It was not used for anything.
|
30
external/nng/cmake/CheckSanitizer.cmake
vendored
Normal file
30
external/nng/cmake/CheckSanitizer.cmake
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
#
|
||||
# Copyright 2019 Staysail Systems, Inc. <info@staysail.tech>
|
||||
# Copyright 2017 Capitar IT Group BV <info@capitar.com>
|
||||
#
|
||||
# This software 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.
|
||||
#
|
||||
|
||||
macro (CheckSanitizer)
|
||||
|
||||
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||
set(NNG_SAN_LIST none address leak memory thread undefined)
|
||||
elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||
set(NNG_SAN_LIST none address leak memory thread undefined)
|
||||
elseif (CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
|
||||
set(NNG_SAN_LIST none address thread undefined)
|
||||
else ()
|
||||
set(NNG_SAN_LIST none)
|
||||
endif ()
|
||||
set (NNG_SANITIZER none CACHE STRING "Sanitizer to use (clang or gcc).")
|
||||
set_property(CACHE NNG_SANITIZER PROPERTY STRINGS ${NNG_SAN_LIST})
|
||||
mark_as_advanced (NNG_SANITIZER)
|
||||
|
||||
if (NOT NNG_SANITIZER STREQUAL "none")
|
||||
set (NNG_C_FLAG_SANITIZER "-fsanitize=${NNG_SANITIZER}")
|
||||
message(STATUS "Enabling sanitizer: ${NNG_C_FLAG_SANITIZER}")
|
||||
endif()
|
||||
endmacro ()
|
86
external/nng/cmake/FindmbedTLS.cmake
vendored
Normal file
86
external/nng/cmake/FindmbedTLS.cmake
vendored
Normal file
|
@ -0,0 +1,86 @@
|
|||
#
|
||||
# Copyright 2020 Staysail Systems, Inc. <info@staysail.tech>
|
||||
# Copyright 2017 Capitar IT Group BV <info@capitar.com>
|
||||
#
|
||||
# This software 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.
|
||||
#
|
||||
|
||||
#
|
||||
# Try to find the Mbed TLS libraries.
|
||||
#
|
||||
# Sets the following:
|
||||
#
|
||||
# MBEDTLS_INCLUDE_DIR - Where to find mbedtls/ssl.h, etc.
|
||||
# MBEDTLS_FOUND - True if we found Mbed TLS.
|
||||
# MBEDTLS_CRYPTO_LIBRARY - The mbedcrypto library.
|
||||
# MBEDTLS_X509_LIBRARY - The mbedx509 library.
|
||||
# MBEDTLS_TLS_LIBRARY - The mbedtls library.
|
||||
# MBEDTLS_LIBRARIES - List of all three Mbed TLS libraries.
|
||||
# MBEDTLS_VERSION - $major.$minor.$revision (e.g. ``2.6.0``).
|
||||
#
|
||||
# Hints:
|
||||
#
|
||||
# Set ``MBEDTLS_ROOT_DIR`` to the root directory of Mbed TLS installation.
|
||||
#
|
||||
|
||||
set(_MBEDTLS_ROOT_HINTS ${MBEDTLS_ROOT_DIR} ENV MBEDTLS_ROOT_DIR)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
find_path(MBEDTLS_INCLUDE_DIR
|
||||
NAMES mbedtls/ssl.h
|
||||
HINTS ${_MBEDTLS_ROOT_HINTS}
|
||||
PATHS /usr/local
|
||||
PATH_SUFFIXES include)
|
||||
|
||||
find_library(MBEDTLS_CRYPTO_LIBRARY
|
||||
NAMES mbedcrypto
|
||||
HINTS ${_MBEDTLS_ROOT_HINTS}
|
||||
PATHS /usr/local
|
||||
PATH_SUFFIXES lib)
|
||||
|
||||
find_library(MBEDTLS_X509_LIBRARY
|
||||
NAMES mbedx509
|
||||
HINTS ${_MBEDTLS_ROOT_HINTS}
|
||||
PATHS /usr/local
|
||||
PATH_SUFFIXES lib)
|
||||
|
||||
find_library(MBEDTLS_TLS_LIBRARY
|
||||
NAMES mbedtls
|
||||
HINTS ${_MBEDTLS_ROOT_HINTS}
|
||||
PATHS /usr/local
|
||||
PATH_SUFFIXES lib)
|
||||
|
||||
set(MBEDTLS_LIBRARIES
|
||||
${MBEDTLS_TLS_LIBRARY}
|
||||
${MBEDTLS_X509_LIBRARY}
|
||||
${MBEDTLS_CRYPTO_LIBRARY})
|
||||
|
||||
if (${MBEDTLS_TLS_LIBRARY-NOTFOUND})
|
||||
message(FATAL_ERROR "Failed to find Mbed TLS library")
|
||||
endif ()
|
||||
|
||||
mark_as_advanced(
|
||||
MBEDSSL_INCLUDE_DIR
|
||||
MBEDTLS_LIBRARIES
|
||||
MBEDTLS_CRYPTO_LIBRARY
|
||||
MBEDTLS_X509_LIBRARY
|
||||
MBEDTLS_TLS_LIBRARY)
|
||||
|
||||
# Extract the version from the header... hopefully it matches the library.
|
||||
if (EXISTS ${MBEDTLS_INCLUDE_DIR}/mbedtls/build_info.h)
|
||||
file(STRINGS ${MBEDTLS_INCLUDE_DIR}/mbedtls/build_info.h _MBEDTLS_VERLINE
|
||||
REGEX "^#define[ \t]+MBEDTLS_VERSION_STRING[\t ].*")
|
||||
else ()
|
||||
file(STRINGS ${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h _MBEDTLS_VERLINE
|
||||
REGEX "^#define[ \t]+MBEDTLS_VERSION_STRING[\t ].*")
|
||||
endif ()
|
||||
|
||||
string(REGEX REPLACE ".*MBEDTLS_VERSION_STRING[\t ]+\"(.*)\"" "\\1" MBEDTLS_VERSION ${_MBEDTLS_VERLINE})
|
||||
|
||||
find_package_handle_standard_args(mbedTLS
|
||||
REQUIRED_VARS MBEDTLS_TLS_LIBRARY MBEDTLS_CRYPTO_LIBRARY MBEDTLS_X509_LIBRARY MBEDTLS_INCLUDE_DIR VERSION_VAR MBEDTLS_VERSION)
|
||||
|
159
external/nng/cmake/NNGHelpers.cmake
vendored
Normal file
159
external/nng/cmake/NNGHelpers.cmake
vendored
Normal file
|
@ -0,0 +1,159 @@
|
|||
#
|
||||
# Copyright 2020 Staysail Systems, Inc. <info@staysail.tech>
|
||||
#
|
||||
# This software 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.
|
||||
#
|
||||
|
||||
# Some NNG helper functions.
|
||||
|
||||
include(CheckFunctionExists)
|
||||
include(CheckSymbolExists)
|
||||
include(CheckStructHasMember)
|
||||
include(CheckLibraryExists)
|
||||
include(CheckCSourceCompiles)
|
||||
|
||||
# nng_sources adds library sources using files in the current directory.
|
||||
function(nng_sources)
|
||||
foreach (f ${ARGN})
|
||||
target_sources(nng PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/${f})
|
||||
target_sources(nng_testing PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/${f})
|
||||
endforeach ()
|
||||
endfunction()
|
||||
|
||||
# nng_headers adds library sources as public headers taken rooted at the include/ directory.
|
||||
function(nng_headers)
|
||||
foreach (f ${ARGN})
|
||||
target_sources(nng PRIVATE ${PROJECT_SOURCE_DIR}/include/${f})
|
||||
target_sources(nng_testing PRIVATE ${PROJECT_SOURCE_DIR}/include/${f})
|
||||
endforeach ()
|
||||
endfunction()
|
||||
|
||||
# nng_defines adds defines unconditionally.
|
||||
# The public library keeps these defines private, but the test library exposes these definitions
|
||||
# as some of our test cases would like to know details about how the library was compiled
|
||||
# as that may modify the tests themselves.
|
||||
function(nng_defines)
|
||||
target_compile_definitions(nng PRIVATE ${ARGN})
|
||||
target_compile_definitions(nng_testing PUBLIC ${ARGN})
|
||||
target_compile_definitions(nng_private INTERFACE ${ARGN})
|
||||
endfunction()
|
||||
|
||||
# nng_link_libraries adds link dependencies to the libraries.
|
||||
function(nng_link_libraries)
|
||||
target_link_libraries(nng PRIVATE ${ARGN})
|
||||
target_link_libraries(nng_testing PRIVATE ${ARGN})
|
||||
endfunction()
|
||||
|
||||
# nng_include_directories adds include directories.
|
||||
function(nng_include_directories)
|
||||
target_include_directories(nng PRIVATE ${ARGN})
|
||||
target_include_directories(nng_testing PRIVATE ${ARGN})
|
||||
endfunction()
|
||||
|
||||
|
||||
# nng_sources_if adds the sources unconditionally to the test library,
|
||||
# but conditionally to the production library. This allows us to get
|
||||
# full test coverage while allowing a minimized delivery.
|
||||
function(nng_sources_if COND)
|
||||
foreach (f ${ARGN})
|
||||
if (${COND})
|
||||
target_sources(nng PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/${f})
|
||||
endif ()
|
||||
target_sources(nng_testing PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/${f})
|
||||
endforeach ()
|
||||
endfunction()
|
||||
|
||||
function(nng_headers_if COND)
|
||||
foreach (f ${ARGN})
|
||||
if (COND)
|
||||
target_sources(nng PRIVATE ${PROJECT_SOURCE_DIR}/include/${f})
|
||||
endif ()
|
||||
target_sources(nng_testing PRIVATE ${PROJECT_SOURCE_DIR}/include/${f})
|
||||
endforeach ()
|
||||
endfunction()
|
||||
|
||||
function(nng_defines_if COND)
|
||||
if (${COND})
|
||||
target_compile_definitions(nng PRIVATE ${ARGN})
|
||||
target_compile_definitions(nng_private INTERFACE ${ARGN})
|
||||
endif ()
|
||||
target_compile_definitions(nng_testing PUBLIC ${ARGN})
|
||||
endfunction()
|
||||
|
||||
function(nng_link_libraries_if COND)
|
||||
if (${COND})
|
||||
target_link_libraries(nng PRIVATE ${ARGN})
|
||||
endif ()
|
||||
target_link_libraries(nng_testing PRIVATE ${ARGN})
|
||||
endfunction()
|
||||
|
||||
function(nng_test NAME)
|
||||
if (NNG_TESTS)
|
||||
add_executable(${NAME} ${NAME}.c ${ARGN})
|
||||
target_link_libraries(${NAME} nng_testing)
|
||||
target_include_directories(${NAME} PRIVATE
|
||||
${PROJECT_SOURCE_DIR}/tests
|
||||
${PROJECT_SOURCE_DIR}/src
|
||||
${PROJECT_SOURCE_DIR}/include)
|
||||
add_test(NAME ${NNG_TEST_PREFIX}.${NAME} COMMAND ${NAME} -t -v)
|
||||
set_tests_properties(${NNG_TEST_PREFIX}.${NAME} PROPERTIES TIMEOUT 180)
|
||||
endif ()
|
||||
endfunction()
|
||||
|
||||
function(nng_test_if COND NAME)
|
||||
if (${COND} AND NNG_TESTS)
|
||||
add_executable(${NAME} ${NAME}.c ${ARGN})
|
||||
target_link_libraries(${NAME} nng_testing)
|
||||
target_include_directories(${NAME} PRIVATE
|
||||
${PROJECT_SOURCE_DIR}/tests
|
||||
${PROJECT_SOURCE_DIR}/src
|
||||
${PROJECT_SOURCE_DIR}/include)
|
||||
add_test(NAME ${NNG_TEST_PREFIX}.${NAME} COMMAND ${NAME} -t -v)
|
||||
set_tests_properties(${NNG_TEST_PREFIX}.${NAME} PROPERTIES TIMEOUT 180)
|
||||
endif ()
|
||||
endfunction()
|
||||
|
||||
function(nng_check_func SYM DEF)
|
||||
check_function_exists(${SYM} ${DEF})
|
||||
if (${DEF})
|
||||
target_compile_definitions(nng PRIVATE ${DEF}=1)
|
||||
target_compile_definitions(nng_testing PUBLIC ${DEF}=1)
|
||||
target_compile_definitions(nng_private INTERFACE ${DEF}=1)
|
||||
endif ()
|
||||
endfunction(nng_check_func)
|
||||
|
||||
function(nng_check_sym SYM HDR DEF)
|
||||
check_symbol_exists(${SYM} ${HDR} ${DEF})
|
||||
if (${DEF})
|
||||
target_compile_definitions(nng PRIVATE ${DEF}=1)
|
||||
target_compile_definitions(nng_testing PUBLIC ${DEF}=1)
|
||||
target_compile_definitions(nng_private INTERFACE ${DEF}=1)
|
||||
endif ()
|
||||
endfunction(nng_check_sym)
|
||||
|
||||
function(nng_check_lib LIB SYM DEF)
|
||||
check_library_exists(${LIB} ${SYM} "" ${DEF})
|
||||
if (${DEF})
|
||||
target_compile_definitions(nng PRIVATE ${DEF}=1)
|
||||
target_compile_definitions(nng_testing PUBLIC ${DEF}=1)
|
||||
target_compile_definitions(nng_private INTERFACE ${DEF}=1)
|
||||
target_link_libraries(nng PRIVATE ${LIB})
|
||||
target_link_libraries(nng_testing PRIVATE ${LIB})
|
||||
endif ()
|
||||
endfunction(nng_check_lib)
|
||||
|
||||
function(nng_check_struct_member STR MEM HDR DEF)
|
||||
check_struct_has_member("struct ${STR}" ${MEM} ${HDR} ${DEF})
|
||||
if (${DEF})
|
||||
target_compile_definitions(nng PRIVATE ${DEF}=1)
|
||||
target_compile_definitions(nng_testing PUBLIC ${DEF}=1)
|
||||
target_compile_definitions(nng_private INTERFACE ${DEF}=1)
|
||||
endif ()
|
||||
endfunction(nng_check_struct_member)
|
||||
|
||||
macro(nng_directory DIR)
|
||||
set(NNG_TEST_PREFIX ${NNG_TEST_PREFIX}.${DIR})
|
||||
endmacro(nng_directory)
|
140
external/nng/cmake/NNGOptions.cmake
vendored
Normal file
140
external/nng/cmake/NNGOptions.cmake
vendored
Normal file
|
@ -0,0 +1,140 @@
|
|||
#
|
||||
# Copyright 2020 Staysail Systems, Inc. <info@staysail.tech>
|
||||
#
|
||||
# This software 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.
|
||||
#
|
||||
|
||||
# NNG Options. These are user configurable knobs.
|
||||
|
||||
include(CMakeDependentOption)
|
||||
|
||||
if (CMAKE_CROSSCOMPILING)
|
||||
set(NNG_NATIVE_BUILD OFF)
|
||||
else ()
|
||||
set(NNG_NATIVE_BUILD ON)
|
||||
endif ()
|
||||
|
||||
# Global options.
|
||||
option(BUILD_SHARED_LIBS "Build shared library" ${BUILD_SHARED_LIBS})
|
||||
|
||||
# We only build command line tools and tests if we are not in a
|
||||
# cross-compile situation. Cross-compiling users who still want to
|
||||
# build these must enable them explicitly. Some of these switches
|
||||
# must be enabled rather early as we use their values later.
|
||||
option(NNG_TESTS "Build and run tests." ${NNG_NATIVE_BUILD})
|
||||
option(NNG_TOOLS "Build extra tools." ${NNG_NATIVE_BUILD})
|
||||
option(NNG_ENABLE_NNGCAT "Enable building nngcat utility." ${NNG_TOOLS})
|
||||
option(NNG_ENABLE_COVERAGE "Enable coverage reporting." OFF)
|
||||
# Eliding deprecated functionality can be used to build a slimmed down
|
||||
# version of the library, or alternatively to test for application
|
||||
# preparedness for expected feature removals (in the next major release.)
|
||||
# Applications can also set the NNG_ELIDE_DEPRECATED preprocessor symbol
|
||||
# before including <nng/nng.h> -- this will prevent declarations from
|
||||
# being exposed to applications, but it will not affect their ABI
|
||||
# availability for existing compiled applications.
|
||||
# Note: Currently this breaks the test suite, so we only do it
|
||||
# for the public library.
|
||||
option(NNG_ELIDE_DEPRECATED "Elide deprecated functionality." OFF)
|
||||
|
||||
option(NNG_ENABLE_STATS "Enable statistics." ON)
|
||||
mark_as_advanced(NNG_ENABLE_STATS)
|
||||
|
||||
# Protocols.
|
||||
option (NNG_PROTO_BUS0 "Enable BUSv0 protocol." ON)
|
||||
mark_as_advanced(NNG_PROTO_BUS0)
|
||||
|
||||
option (NNG_PROTO_PAIR0 "Enable PAIRv0 protocol." ON)
|
||||
mark_as_advanced(NNG_PROTO_PAIR0)
|
||||
|
||||
option (NNG_PROTO_PAIR1 "Enable PAIRv1 protocol." ON)
|
||||
mark_as_advanced(NNG_PROTO_PAIR1)
|
||||
|
||||
option (NNG_PROTO_PUSH0 "Enable PUSHv0 protocol." ON)
|
||||
mark_as_advanced(NNG_PROTO_PUSH0)
|
||||
|
||||
option (NNG_PROTO_PULL0 "Enable PULLv0 protocol." ON)
|
||||
mark_as_advanced(NNG_PROTO_PULL0)
|
||||
|
||||
option (NNG_PROTO_PUB0 "Enable PUBv0 protocol." ON)
|
||||
mark_as_advanced(NNG_PROTO_PUB0)
|
||||
|
||||
option (NNG_PROTO_SUB0 "Enable SUBv0 protocol." ON)
|
||||
mark_as_advanced(NNG_PROTO_SUB0)
|
||||
|
||||
option(NNG_PROTO_REQ0 "Enable REQv0 protocol." ON)
|
||||
mark_as_advanced(NNG_PROTO_REQ0)
|
||||
|
||||
option(NNG_PROTO_REP0 "Enable REPv0 protocol." ON)
|
||||
mark_as_advanced(NNG_PROTO_REP0)
|
||||
|
||||
option (NNG_PROTO_RESPONDENT0 "Enable RESPONDENTv0 protocol." ON)
|
||||
mark_as_advanced(NNG_PROTO_RESPONDENT0)
|
||||
|
||||
option (NNG_PROTO_SURVEYOR0 "Enable SURVEYORv0 protocol." ON)
|
||||
mark_as_advanced(NNG_PROTO_SURVEYOR0)
|
||||
|
||||
# TLS support.
|
||||
|
||||
# Enabling TLS is required to enable support for the TLS transport
|
||||
# and WSS. It does require a 3rd party TLS engine to be selected.
|
||||
option(NNG_ENABLE_TLS "Enable TLS support." OFF)
|
||||
if (NNG_ENABLE_TLS)
|
||||
set(NNG_SUPP_TLS ON)
|
||||
endif ()
|
||||
|
||||
if (NNG_ENABLE_TLS)
|
||||
set(NNG_TLS_ENGINES mbed wolf none)
|
||||
# We assume Mbed for now. (Someday replaced perhaps with Bear.)
|
||||
set(NNG_TLS_ENGINE mbed CACHE STRING "TLS engine to use.")
|
||||
set_property(CACHE NNG_TLS_ENGINE PROPERTY STRINGS ${NNG_TLS_ENGINES})
|
||||
else ()
|
||||
set(NNG_TLS_ENGINE none)
|
||||
endif ()
|
||||
|
||||
# HTTP API support.
|
||||
option (NNG_ENABLE_HTTP "Enable HTTP API." ON)
|
||||
if (NNG_ENABLE_HTTP)
|
||||
set(NNG_SUPP_HTTP ON)
|
||||
endif()
|
||||
mark_as_advanced(NNG_ENABLE_HTTP)
|
||||
|
||||
#
|
||||
# Transport Options.
|
||||
#
|
||||
|
||||
option (NNG_TRANSPORT_INPROC "Enable inproc transport." ON)
|
||||
mark_as_advanced(NNG_TRANSPORT_INPROC)
|
||||
|
||||
option (NNG_TRANSPORT_IPC "Enable IPC transport." ON)
|
||||
mark_as_advanced(NNG_TRANSPORT_IPC)
|
||||
|
||||
# TCP transport
|
||||
option (NNG_TRANSPORT_TCP "Enable TCP transport." ON)
|
||||
mark_as_advanced(NNG_TRANSPORT_TCP)
|
||||
|
||||
# TLS transport
|
||||
option (NNG_TRANSPORT_TLS "Enable TLS transport." ON)
|
||||
mark_as_advanced(NNG_TRANSPORT_TLS)
|
||||
|
||||
# WebSocket
|
||||
option (NNG_TRANSPORT_WS "Enable WebSocket transport." ON)
|
||||
mark_as_advanced(NNG_TRANSPORT_WS)
|
||||
|
||||
CMAKE_DEPENDENT_OPTION(NNG_TRANSPORT_WSS "Enable WSS transport." ON
|
||||
"NNG_ENABLE_TLS" OFF)
|
||||
mark_as_advanced(NNG_TRANSPORT_WSS)
|
||||
|
||||
# ZeroTier
|
||||
option (NNG_TRANSPORT_ZEROTIER "Enable ZeroTier transport (requires libzerotiercore)." OFF)
|
||||
mark_as_advanced(NNG_TRANSPORT_ZEROTIER)
|
||||
|
||||
if (NNG_TRANSPORT_WS OR NNG_TRANSPORT_WSS)
|
||||
# Make sure things we *MUST* have are enabled.
|
||||
set(NNG_SUPP_WEBSOCKET ON)
|
||||
set(NNG_SUPP_HTTP ON)
|
||||
set(NNG_SUPP_BASE64 ON)
|
||||
set(NNG_SUPP_SHA1 ON)
|
||||
endif()
|
26
external/nng/cmake/nng-config.cmake.in
vendored
Normal file
26
external/nng/cmake/nng-config.cmake.in
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Copyright 2021 Staysail Systems, Inc. <info@staysail.tech>
|
||||
#
|
||||
# This software 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.
|
||||
|
||||
|
||||
@PACKAGE_INIT@
|
||||
|
||||
set(NNG_VERSION_MAJOR "@NNG_MAJOR_VERSION@")
|
||||
set(NNG_VERSION_MINOR "@NNG_MINOR_VERSION@")
|
||||
set(NNG_VERSION_PATCH "@NNG_PATCH_VERSION@")
|
||||
|
||||
set_and_check(NNG_INCLUDE_DIRS "@PACKAGE_INCLUDE_INSTALL_DIRS@")
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/nng-targets.cmake")
|
||||
|
||||
# Make sure we find packages for our dependencies
|
||||
foreach(_PKG IN ITEMS @NNG_PKGS@)
|
||||
find_package(${_PKG} REQUIRED)
|
||||
endforeach ()
|
||||
|
||||
set(NNG_LIBRARY nng::nng)
|
||||
|
||||
check_required_components(@PROJECT_NAME@)
|
24
external/nng/demo/async/CMakeLists.txt
vendored
Normal file
24
external/nng/demo/async/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
#
|
||||
# Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||||
# Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
|
||||
#
|
||||
# This software 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.
|
||||
|
||||
cmake_minimum_required (VERSION 2.8.7)
|
||||
|
||||
project(nng-asyncdemo)
|
||||
|
||||
set(PARALLEL 128 CACHE STRING "Parallelism (min 4, max 1000)")
|
||||
|
||||
# Call this from your own project's makefile.
|
||||
find_package(nng CONFIG REQUIRED)
|
||||
|
||||
add_executable(server server.c)
|
||||
target_link_libraries(server nng::nng)
|
||||
target_compile_definitions(server PRIVATE -DPARALLEL=${PARALLEL})
|
||||
|
||||
add_executable(client client.c)
|
||||
target_link_libraries(client nng::nng)
|
50
external/nng/demo/async/README.adoc
vendored
Normal file
50
external/nng/demo/async/README.adoc
vendored
Normal file
|
@ -0,0 +1,50 @@
|
|||
= async
|
||||
|
||||
This is a simple asynchronous demo, that demonstrates use of the contexts
|
||||
and asynchronous message handling and operations, to obtain highly concurrent
|
||||
processing with minimal fuss.
|
||||
|
||||
== Compiling
|
||||
|
||||
This is set up for configuration with CMake for ease of use.
|
||||
|
||||
You can override the level of concurrency with the `PARALLEL` option.
|
||||
|
||||
This determines how many requests the server will accept
|
||||
at a time, and keep outstanding. Note that for our toy implementation,
|
||||
we create this many "logical" flows of execution (contexts) (these are
|
||||
_NOT_ threads), where a request is followed by a reply.
|
||||
|
||||
The value of `PARALLEL` must be at least one, and may be as large
|
||||
as your memory will permit. (The default value is 128.) Probably
|
||||
you want the value to be small enough to ensure that you have enough
|
||||
file descriptors. (You can create more contexts than this, but generally
|
||||
you can't have more than one client per descriptor. Contexts can be used
|
||||
on the client side to support many thousands of concurrent requests over
|
||||
even just a single TCP connection, however.)
|
||||
|
||||
You can also build this all by hand with Make or whatever.
|
||||
|
||||
On UNIX-style systems:
|
||||
|
||||
[source, bash]
|
||||
----
|
||||
% export CPPFLAGS="-D PARALLEL=32 -I /usr/local/include"
|
||||
% export LDFLAGS="-L /usr/local/lib -lnng"
|
||||
% export CC="cc"
|
||||
% ${CC} ${CPPFLAGS} server.c -o server ${LDFLAGS}
|
||||
% ${CC} ${CPPFLAGS} client.c -o client ${LDFLAGS}
|
||||
----
|
||||
|
||||
== Running
|
||||
|
||||
The easiest thing is to simply use the `run.sh` script, which
|
||||
sends COUNT (10) random jobs to the server in parallel.
|
||||
|
||||
You can of course run the client and server manually instead.
|
||||
|
||||
The server takes the address (url) as its only argument.
|
||||
|
||||
The client takes the address (url), followed by the number of
|
||||
milliseconds the server should "wait" before responding (to simulate
|
||||
an expensive operation.)
|
95
external/nng/demo/async/client.c
vendored
Normal file
95
external/nng/demo/async/client.c
vendored
Normal file
|
@ -0,0 +1,95 @@
|
|||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
|
||||
// Copyright 2018 Capitar IT Group BV <info@capitoar.com>
|
||||
//
|
||||
// This software 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.
|
||||
//
|
||||
|
||||
// This program is just a simple client application for our demo server.
|
||||
// It is in a separate file to keep the server code clearer to understand.
|
||||
//
|
||||
// Our demonstration application layer protocol is simple. The client sends
|
||||
// a number of milliseconds to wait before responding. The server just gives
|
||||
// back an empty reply after waiting that long.
|
||||
|
||||
// For example:
|
||||
//
|
||||
// % ./server tcp://127.0.0.1:5555 &
|
||||
// % ./client tcp://127.0.0.1:5555 323
|
||||
// Request took 324 milliseconds.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <nng/nng.h>
|
||||
#include <nng/protocol/reqrep0/req.h>
|
||||
#include <nng/supplemental/util/platform.h>
|
||||
|
||||
void
|
||||
fatal(const char *func, int rv)
|
||||
{
|
||||
fprintf(stderr, "%s: %s\n", func, nng_strerror(rv));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* The client runs just once, and then returns. */
|
||||
int
|
||||
client(const char *url, const char *msecstr)
|
||||
{
|
||||
nng_socket sock;
|
||||
int rv;
|
||||
nng_msg * msg;
|
||||
nng_time start;
|
||||
nng_time end;
|
||||
unsigned msec;
|
||||
|
||||
msec = atoi(msecstr);
|
||||
|
||||
if ((rv = nng_req0_open(&sock)) != 0) {
|
||||
fatal("nng_req0_open", rv);
|
||||
}
|
||||
|
||||
if ((rv = nng_dial(sock, url, NULL, 0)) != 0) {
|
||||
fatal("nng_dial", rv);
|
||||
}
|
||||
|
||||
start = nng_clock();
|
||||
|
||||
if ((rv = nng_msg_alloc(&msg, 0)) != 0) {
|
||||
fatal("nng_msg_alloc", rv);
|
||||
}
|
||||
if ((rv = nng_msg_append_u32(msg, msec)) != 0) {
|
||||
fatal("nng_msg_append_u32", rv);
|
||||
}
|
||||
|
||||
if ((rv = nng_sendmsg(sock, msg, 0)) != 0) {
|
||||
fatal("nng_send", rv);
|
||||
}
|
||||
|
||||
if ((rv = nng_recvmsg(sock, &msg, 0)) != 0) {
|
||||
fatal("nng_recvmsg", rv);
|
||||
}
|
||||
end = nng_clock();
|
||||
nng_msg_free(msg);
|
||||
nng_close(sock);
|
||||
|
||||
printf("Request took %u milliseconds.\n", (uint32_t)(end - start));
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "Usage: %s <url> <secs>\n", argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
rc = client(argv[1], argv[2]);
|
||||
exit(rc == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
|
||||
}
|
27
external/nng/demo/async/run.sh
vendored
Executable file
27
external/nng/demo/async/run.sh
vendored
Executable file
|
@ -0,0 +1,27 @@
|
|||
#!/bin/bash
|
||||
|
||||
ADDR=ipc:///tmp/async_demo
|
||||
COUNT=10
|
||||
|
||||
./server $ADDR &
|
||||
SERVER_PID=$!
|
||||
trap "kill $SERVER_PID" 0
|
||||
typeset -a CLIENT_PID
|
||||
i=0
|
||||
sleep 1
|
||||
while (( i < COUNT ))
|
||||
do
|
||||
i=$(( i + 1 ))
|
||||
rnd=$(( RANDOM % 1000 + 500 ))
|
||||
echo "Starting client $i: server replies after $rnd msec"
|
||||
./client $ADDR $rnd &
|
||||
eval CLIENT_PID[$i]=$!
|
||||
done
|
||||
|
||||
i=0
|
||||
while (( i < COUNT ))
|
||||
do
|
||||
i=$(( i + 1 ))
|
||||
wait ${CLIENT_PID[$i]}
|
||||
done
|
||||
kill $SERVER_PID
|
178
external/nng/demo/async/server.c
vendored
Normal file
178
external/nng/demo/async/server.c
vendored
Normal file
|
@ -0,0 +1,178 @@
|
|||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
|
||||
// Copyright 2018 Capitar IT Group BV <info@capitoar.com>
|
||||
//
|
||||
// This software 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.
|
||||
//
|
||||
|
||||
// This program serves as an example for how to write an async RPC service,
|
||||
// using the request/reply pattern and contexts (nng_ctx(5)). The server
|
||||
// allocates a number of contexts up front, which determines the amount of
|
||||
// parallelism possible. The callbacks are handled asynchronously, so
|
||||
// this could be done by threads, or something similar. For our uses we
|
||||
// make use of an event driven architecture that we already have available.
|
||||
|
||||
// Our demonstration application layer protocol is simple. The client sends
|
||||
// a number of milliseconds to wait before responding. The server just gives
|
||||
// back an empty reply after waiting that long.
|
||||
|
||||
// To run this program, start the server as async_demo <url> -s
|
||||
// Then connect to it with the client as async_client <url> <msec>.
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// % ./server tcp://127.0.0.1:5555 &
|
||||
// % ./client tcp://127.0.0.1:5555 323
|
||||
// Request took 324 milliseconds.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <nng/nng.h>
|
||||
#include <nng/protocol/reqrep0/rep.h>
|
||||
#include <nng/supplemental/util/platform.h>
|
||||
|
||||
// Parallel is the maximum number of outstanding requests we can handle.
|
||||
// This is *NOT* the number of threads in use, but instead represents
|
||||
// outstanding work items. Select a small number to reduce memory size.
|
||||
// (Each one of these can be thought of as a request-reply loop.) Note
|
||||
// that you will probably run into limitations on the number of open file
|
||||
// descriptors if you set this too high. (If not for that limit, this could
|
||||
// be set in the thousands, each context consumes a couple of KB.)
|
||||
#ifndef PARALLEL
|
||||
#define PARALLEL 128
|
||||
#endif
|
||||
|
||||
// The server keeps a list of work items, sorted by expiration time,
|
||||
// so that we can use this to set the timeout to the correct value for
|
||||
// use in poll.
|
||||
struct work {
|
||||
enum { INIT, RECV, WAIT, SEND } state;
|
||||
nng_aio *aio;
|
||||
nng_msg *msg;
|
||||
nng_ctx ctx;
|
||||
};
|
||||
|
||||
void
|
||||
fatal(const char *func, int rv)
|
||||
{
|
||||
fprintf(stderr, "%s: %s\n", func, nng_strerror(rv));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void
|
||||
server_cb(void *arg)
|
||||
{
|
||||
struct work *work = arg;
|
||||
nng_msg * msg;
|
||||
int rv;
|
||||
uint32_t when;
|
||||
|
||||
switch (work->state) {
|
||||
case INIT:
|
||||
work->state = RECV;
|
||||
nng_ctx_recv(work->ctx, work->aio);
|
||||
break;
|
||||
case RECV:
|
||||
if ((rv = nng_aio_result(work->aio)) != 0) {
|
||||
fatal("nng_ctx_recv", rv);
|
||||
}
|
||||
msg = nng_aio_get_msg(work->aio);
|
||||
if ((rv = nng_msg_trim_u32(msg, &when)) != 0) {
|
||||
// bad message, just ignore it.
|
||||
nng_msg_free(msg);
|
||||
nng_ctx_recv(work->ctx, work->aio);
|
||||
return;
|
||||
}
|
||||
work->msg = msg;
|
||||
work->state = WAIT;
|
||||
nng_sleep_aio(when, work->aio);
|
||||
break;
|
||||
case WAIT:
|
||||
// We could add more data to the message here.
|
||||
nng_aio_set_msg(work->aio, work->msg);
|
||||
work->msg = NULL;
|
||||
work->state = SEND;
|
||||
nng_ctx_send(work->ctx, work->aio);
|
||||
break;
|
||||
case SEND:
|
||||
if ((rv = nng_aio_result(work->aio)) != 0) {
|
||||
nng_msg_free(work->msg);
|
||||
fatal("nng_ctx_send", rv);
|
||||
}
|
||||
work->state = RECV;
|
||||
nng_ctx_recv(work->ctx, work->aio);
|
||||
break;
|
||||
default:
|
||||
fatal("bad state!", NNG_ESTATE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
struct work *
|
||||
alloc_work(nng_socket sock)
|
||||
{
|
||||
struct work *w;
|
||||
int rv;
|
||||
|
||||
if ((w = nng_alloc(sizeof(*w))) == NULL) {
|
||||
fatal("nng_alloc", NNG_ENOMEM);
|
||||
}
|
||||
if ((rv = nng_aio_alloc(&w->aio, server_cb, w)) != 0) {
|
||||
fatal("nng_aio_alloc", rv);
|
||||
}
|
||||
if ((rv = nng_ctx_open(&w->ctx, sock)) != 0) {
|
||||
fatal("nng_ctx_open", rv);
|
||||
}
|
||||
w->state = INIT;
|
||||
return (w);
|
||||
}
|
||||
|
||||
// The server runs forever.
|
||||
int
|
||||
server(const char *url)
|
||||
{
|
||||
nng_socket sock;
|
||||
struct work *works[PARALLEL];
|
||||
int rv;
|
||||
int i;
|
||||
|
||||
/* Create the socket. */
|
||||
rv = nng_rep0_open(&sock);
|
||||
if (rv != 0) {
|
||||
fatal("nng_rep0_open", rv);
|
||||
}
|
||||
|
||||
for (i = 0; i < PARALLEL; i++) {
|
||||
works[i] = alloc_work(sock);
|
||||
}
|
||||
|
||||
if ((rv = nng_listen(sock, url, NULL, 0)) != 0) {
|
||||
fatal("nng_listen", rv);
|
||||
}
|
||||
|
||||
for (i = 0; i < PARALLEL; i++) {
|
||||
server_cb(works[i]); // this starts them going (INIT state)
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
nng_msleep(3600000); // neither pause() nor sleep() portable
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Usage: %s <url>\n", argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
rc = server(argv[1]);
|
||||
exit(rc == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
|
||||
}
|
18
external/nng/demo/http_client/CMakeLists.txt
vendored
Normal file
18
external/nng/demo/http_client/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
#
|
||||
# Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||||
# Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
|
||||
#
|
||||
# This software 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.
|
||||
|
||||
cmake_minimum_required (VERSION 2.8.7)
|
||||
|
||||
project(http_client)
|
||||
|
||||
# Call this from your own project's makefile.
|
||||
find_package(nng CONFIG REQUIRED)
|
||||
|
||||
add_executable(http_client http_client.c)
|
||||
target_link_libraries(http_client nng::nng)
|
52
external/nng/demo/http_client/README.adoc
vendored
Normal file
52
external/nng/demo/http_client/README.adoc
vendored
Normal file
|
@ -0,0 +1,52 @@
|
|||
= http_client
|
||||
|
||||
This is a very simple HTTP client. It only performs HTTP GET
|
||||
operations, and does not follow HTTP redirects. Think of it as
|
||||
a trivialized version of cURL. It is super simple, taking the
|
||||
URL on the command line, and emitting the results to stdout.
|
||||
|
||||
For clarity, we are eliding TLS support.
|
||||
|
||||
It may not work on all systems, but it should work anywhere that
|
||||
both the standard C library and nng itself are available.
|
||||
|
||||
We check for errors, but no effort is made to clean up resources,
|
||||
since this program just exits. In longer running programs or libraries,
|
||||
callers should take care to clean up things that they allocate.
|
||||
|
||||
Unfortunately many famous sites use redirects (usually to HTTPS
|
||||
sites), so it's not a very useful replacement for cURL.
|
||||
|
||||
== Compiling
|
||||
|
||||
The following is an example typical of UNIX and similar systems like
|
||||
Linux and macOS:
|
||||
|
||||
[source, bash]
|
||||
----
|
||||
% export CPPFLAGS="-I /usr/local/include"
|
||||
% export LDFLAGS="-L /usr/local/lib -lnng"
|
||||
% export CC="cc"
|
||||
% ${CC} ${CPPFLAGS} http_client.c -o http_client ${LDFLAGS}
|
||||
----
|
||||
|
||||
Alternatively, CMake can be used. Here's an example if you have
|
||||
Ninja build handy (highly recommended):
|
||||
|
||||
[source, bash]
|
||||
----
|
||||
% mkdir build
|
||||
% cd build
|
||||
% cmake -G Ninja ..
|
||||
% ninja
|
||||
----
|
||||
|
||||
== Running
|
||||
|
||||
Make sure you specify the full URL (if the root page include
|
||||
the simple "/". The URL parser does not add it for you automatically.)
|
||||
|
||||
[source, bash]
|
||||
----
|
||||
% ./http_client http://httpbin.org/ip
|
||||
----
|
147
external/nng/demo/http_client/http_client.c
vendored
Normal file
147
external/nng/demo/http_client/http_client.c
vendored
Normal file
|
@ -0,0 +1,147 @@
|
|||
//
|
||||
// Copyright 2018 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
|
||||
// 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.
|
||||
//
|
||||
|
||||
// This is a very simple HTTP client. It only performs HTTP GET
|
||||
// operations, and does not follow HTTP redirects. Think of it as
|
||||
// a trivialized version of CURL. It is super simple, taking the
|
||||
// URL on the command line, and emitting the results to stdout.
|
||||
// For clarity, we are eliding TLS support.
|
||||
|
||||
// It may not work on all systems, but it should work anywhere that
|
||||
// both the standard C library and nng itself are available.
|
||||
|
||||
// We check for errors, but no effort is made to clean up resources,
|
||||
// since this program just exits. In longer running programs or libraries,
|
||||
// callers should take care to clean up things that they allocate.
|
||||
|
||||
// Unfortunately many famous sites use redirects, so you won't see that
|
||||
// emitted.
|
||||
|
||||
// Example usage:
|
||||
//
|
||||
// % export CPPFLAGS="-I /usr/local/include"
|
||||
// % export LDFLAGS="-L /usr/local/lib -lnng"
|
||||
// % export CC="cc"
|
||||
// % ${CC} ${CPPFLAGS} http_client.c -o http_client ${LDFLAGS}
|
||||
// % ./http_client http://httpbin.org/ip
|
||||
//
|
||||
|
||||
#include <nng/nng.h>
|
||||
#include <nng/supplemental/http/http.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void
|
||||
fatal(int rv)
|
||||
{
|
||||
fprintf(stderr, "%s\n", nng_strerror(rv));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
nng_http_client *client;
|
||||
nng_http_conn * conn;
|
||||
nng_url * url;
|
||||
nng_aio * aio;
|
||||
nng_http_req * req;
|
||||
nng_http_res * res;
|
||||
const char * hdr;
|
||||
int rv;
|
||||
int len;
|
||||
void * data;
|
||||
nng_iov iov;
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "No URL supplied!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (((rv = nng_url_parse(&url, argv[1])) != 0) ||
|
||||
((rv = nng_http_client_alloc(&client, url)) != 0) ||
|
||||
((rv = nng_http_req_alloc(&req, url)) != 0) ||
|
||||
((rv = nng_http_res_alloc(&res)) != 0) ||
|
||||
((rv = nng_aio_alloc(&aio, NULL, NULL)) != 0)) {
|
||||
fatal(rv);
|
||||
}
|
||||
|
||||
// Start connection process...
|
||||
nng_http_client_connect(client, aio);
|
||||
|
||||
// Wait for it to finish.
|
||||
nng_aio_wait(aio);
|
||||
if ((rv = nng_aio_result(aio)) != 0) {
|
||||
fatal(rv);
|
||||
}
|
||||
|
||||
// Get the connection, at the 0th output.
|
||||
conn = nng_aio_get_output(aio, 0);
|
||||
|
||||
// Request is already set up with URL, and for GET via HTTP/1.1.
|
||||
// The Host: header is already set up too.
|
||||
|
||||
// Send the request, and wait for that to finish.
|
||||
nng_http_conn_write_req(conn, req, aio);
|
||||
nng_aio_wait(aio);
|
||||
|
||||
if ((rv = nng_aio_result(aio)) != 0) {
|
||||
fatal(rv);
|
||||
}
|
||||
|
||||
// Read a response.
|
||||
nng_http_conn_read_res(conn, res, aio);
|
||||
nng_aio_wait(aio);
|
||||
|
||||
if ((rv = nng_aio_result(aio)) != 0) {
|
||||
fatal(rv);
|
||||
}
|
||||
|
||||
if (nng_http_res_get_status(res) != NNG_HTTP_STATUS_OK) {
|
||||
fprintf(stderr, "HTTP Server Responded: %d %s\n",
|
||||
nng_http_res_get_status(res),
|
||||
nng_http_res_get_reason(res));
|
||||
}
|
||||
|
||||
// This only supports regular transfer encoding (no Chunked-Encoding,
|
||||
// and a Content-Length header is required.)
|
||||
if ((hdr = nng_http_res_get_header(res, "Content-Length")) == NULL) {
|
||||
fprintf(stderr, "Missing Content-Length header.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
len = atoi(hdr);
|
||||
if (len == 0) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
// Allocate a buffer to receive the body data.
|
||||
data = malloc(len);
|
||||
|
||||
// Set up a single iov to point to the buffer.
|
||||
iov.iov_len = len;
|
||||
iov.iov_buf = data;
|
||||
|
||||
// Following never fails with fewer than 5 elements.
|
||||
nng_aio_set_iov(aio, 1, &iov);
|
||||
|
||||
// Now attempt to receive the data.
|
||||
nng_http_conn_read_all(conn, aio);
|
||||
|
||||
// Wait for it to complete.
|
||||
nng_aio_wait(aio);
|
||||
|
||||
if ((rv = nng_aio_result(aio)) != 0) {
|
||||
fatal(rv);
|
||||
}
|
||||
|
||||
fwrite(data, 1, len, stdout);
|
||||
return (0);
|
||||
}
|
20
external/nng/demo/raw/CMakeLists.txt
vendored
Normal file
20
external/nng/demo/raw/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
#
|
||||
# Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||||
# Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
|
||||
#
|
||||
# This software 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.
|
||||
|
||||
cmake_minimum_required (VERSION 2.8.7)
|
||||
|
||||
project(raw)
|
||||
|
||||
set(PARALLEL 128 CACHE STRING "Parallelism (min 4, max 1000)")
|
||||
|
||||
find_package(nng CONFIG REQUIRED)
|
||||
|
||||
add_executable(raw raw.c)
|
||||
target_link_libraries(raw nng::nng)
|
||||
target_compile_definitions(raw PRIVATE -DPARALLEL=${PARALLEL})
|
64
external/nng/demo/raw/README.adoc
vendored
Normal file
64
external/nng/demo/raw/README.adoc
vendored
Normal file
|
@ -0,0 +1,64 @@
|
|||
= raw
|
||||
|
||||
This is a simple asynchronous demo, that demonstrates use of the RAW
|
||||
sockets with a server, along with async message handling, to obtain a
|
||||
very high level of asynchronous operation, suitable for use in a highly
|
||||
concurrent server application.
|
||||
|
||||
== Compiling
|
||||
|
||||
You can override the level of concurrency with the `PARALLEL` option.
|
||||
|
||||
This determines how many requests the server will accept
|
||||
at a time, and keep outstanding. Note that for our toy
|
||||
implementation, we create this many "logical" flows of execution
|
||||
(these are _NOT_ threads), where a request is followed by a reply.
|
||||
|
||||
The value of `PARALLEL` must be at least one, and may be as large
|
||||
as your memory will permit. (The default value is 32.)
|
||||
|
||||
The best way to build is using cmake and Ninja build:
|
||||
|
||||
[source, bash]
|
||||
----
|
||||
% mkdir build
|
||||
% cd build
|
||||
% cmake -G Ninja ..
|
||||
% ninja
|
||||
----
|
||||
|
||||
You can also build the hard way. For example, on UNIX-style systems:
|
||||
|
||||
[source, bash]
|
||||
----
|
||||
% export CPPFLAGS="-D PARALLEL=32 -I /usr/local/include"
|
||||
% export LDFLAGS="-L /usr/local/lib -lnng"
|
||||
% export CC="cc"
|
||||
% ${CC} ${CPPFLAGS} raw.c -o raw ${LDFLAGS}
|
||||
----
|
||||
|
||||
== Running
|
||||
|
||||
To run the server, use the arguments `__url__ -s`.
|
||||
|
||||
To run the client, use the arguments `__url__ __msec__`.
|
||||
|
||||
The _msec_ is a "delay" time that server will wait before responding.
|
||||
We have these delays so simulate long running work.
|
||||
|
||||
In the following example, all of the clients should complete within
|
||||
2 seconds. (Assuming `PARALLEL` is defined to be large enough.)
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
% export URL="tcp://127.0.0.1:55995"
|
||||
# start the server
|
||||
% ./raw $URL -s &
|
||||
# start a bunch of clients
|
||||
# Note that these all run concurrently!
|
||||
% ./raw $URL 2 &
|
||||
% ./raw $URL 2 &
|
||||
% ./raw $URL 2 &
|
||||
% ./raw $URL 2 &
|
||||
% ./raw $URL 2 &
|
||||
----
|
220
external/nng/demo/raw/raw.c
vendored
Normal file
220
external/nng/demo/raw/raw.c
vendored
Normal file
|
@ -0,0 +1,220 @@
|
|||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
|
||||
// Copyright 2018 Capitar IT Group BV <info@capitoar.com>
|
||||
//
|
||||
// This software 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.
|
||||
//
|
||||
|
||||
// This program serves as an example for how to write an async RPC service,
|
||||
// using the RAW request/reply pattern and nn_poll. The server receives
|
||||
// messages and keeps them on a list, replying to them.
|
||||
|
||||
// Our demonstration application layer protocol is simple. The client sends
|
||||
// a number of milliseconds to wait before responding. The server just gives
|
||||
// back an empty reply after waiting that long.
|
||||
|
||||
// To run this program, start the server as async_demo <url> -s
|
||||
// Then connect to it with the client as async_client <url> <msec>.
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// % ./async tcp://127.0.0.1:5555 -s &
|
||||
// % ./async tcp://127.0.0.1:5555 323
|
||||
// Request took 324 milliseconds.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <nng/nng.h>
|
||||
#include <nng/protocol/reqrep0/rep.h>
|
||||
#include <nng/protocol/reqrep0/req.h>
|
||||
#include <nng/supplemental/util/platform.h>
|
||||
|
||||
// Parallel is the maximum number of outstanding requests we can handle.
|
||||
// This is *NOT* the number of threads in use, but instead represents
|
||||
// outstanding work items. Select a small number to reduce memory size.
|
||||
// (Each one of these can be thought of as a request-reply loop.)
|
||||
#ifndef PARALLEL
|
||||
#define PARALLEL 32
|
||||
#endif
|
||||
|
||||
// The server keeps a list of work items, sorted by expiration time,
|
||||
// so that we can use this to set the timeout to the correct value for
|
||||
// use in poll.
|
||||
struct work {
|
||||
enum { INIT, RECV, WAIT, SEND } state;
|
||||
nng_aio * aio;
|
||||
nng_socket sock;
|
||||
nng_msg * msg;
|
||||
};
|
||||
|
||||
void
|
||||
fatal(const char *func, int rv)
|
||||
{
|
||||
fprintf(stderr, "%s: %s\n", func, nng_strerror(rv));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void
|
||||
server_cb(void *arg)
|
||||
{
|
||||
struct work *work = arg;
|
||||
nng_msg * msg;
|
||||
int rv;
|
||||
uint32_t when;
|
||||
|
||||
switch (work->state) {
|
||||
case INIT:
|
||||
work->state = RECV;
|
||||
nng_recv_aio(work->sock, work->aio);
|
||||
break;
|
||||
case RECV:
|
||||
if ((rv = nng_aio_result(work->aio)) != 0) {
|
||||
fatal("nng_recv_aio", rv);
|
||||
}
|
||||
msg = nng_aio_get_msg(work->aio);
|
||||
if ((rv = nng_msg_trim_u32(msg, &when)) != 0) {
|
||||
// bad message, just ignore it.
|
||||
nng_msg_free(msg);
|
||||
nng_recv_aio(work->sock, work->aio);
|
||||
return;
|
||||
}
|
||||
work->msg = msg;
|
||||
work->state = WAIT;
|
||||
nng_sleep_aio(when, work->aio);
|
||||
break;
|
||||
case WAIT:
|
||||
// We could add more data to the message here.
|
||||
nng_aio_set_msg(work->aio, work->msg);
|
||||
work->msg = NULL;
|
||||
work->state = SEND;
|
||||
nng_send_aio(work->sock, work->aio);
|
||||
break;
|
||||
case SEND:
|
||||
if ((rv = nng_aio_result(work->aio)) != 0) {
|
||||
nng_msg_free(work->msg);
|
||||
fatal("nng_send_aio", rv);
|
||||
}
|
||||
work->state = RECV;
|
||||
nng_recv_aio(work->sock, work->aio);
|
||||
break;
|
||||
default:
|
||||
fatal("bad state!", NNG_ESTATE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
struct work *
|
||||
alloc_work(nng_socket sock)
|
||||
{
|
||||
struct work *w;
|
||||
int rv;
|
||||
|
||||
if ((w = nng_alloc(sizeof(*w))) == NULL) {
|
||||
fatal("nng_alloc", NNG_ENOMEM);
|
||||
}
|
||||
if ((rv = nng_aio_alloc(&w->aio, server_cb, w)) != 0) {
|
||||
fatal("nng_aio_alloc", rv);
|
||||
}
|
||||
w->state = INIT;
|
||||
w->sock = sock;
|
||||
return (w);
|
||||
}
|
||||
|
||||
// The server runs forever.
|
||||
int
|
||||
server(const char *url)
|
||||
{
|
||||
nng_socket sock;
|
||||
struct work *works[PARALLEL];
|
||||
int rv;
|
||||
int i;
|
||||
|
||||
/* Create the socket. */
|
||||
rv = nng_rep0_open_raw(&sock);
|
||||
if (rv != 0) {
|
||||
fatal("nng_rep0_open", rv);
|
||||
}
|
||||
|
||||
for (i = 0; i < PARALLEL; i++) {
|
||||
works[i] = alloc_work(sock);
|
||||
}
|
||||
|
||||
if ((rv = nng_listen(sock, url, NULL, 0)) != 0) {
|
||||
fatal("nng_listen", rv);
|
||||
}
|
||||
|
||||
for (i = 0; i < PARALLEL; i++) {
|
||||
server_cb(works[i]); // this starts them going (INIT state)
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
nng_msleep(3600000); // neither pause() nor sleep() portable
|
||||
}
|
||||
}
|
||||
|
||||
/* The client runs just once, and then returns. */
|
||||
int
|
||||
client(const char *url, const char *msecstr)
|
||||
{
|
||||
nng_socket sock;
|
||||
int rv;
|
||||
nng_msg * msg;
|
||||
nng_time start;
|
||||
nng_time end;
|
||||
unsigned msec;
|
||||
|
||||
msec = atoi(msecstr) * 1000;
|
||||
|
||||
if ((rv = nng_req0_open(&sock)) != 0) {
|
||||
fatal("nng_req0_open", rv);
|
||||
}
|
||||
|
||||
if ((rv = nng_dial(sock, url, NULL, 0)) != 0) {
|
||||
fatal("nng_dial", rv);
|
||||
}
|
||||
|
||||
start = nng_clock();
|
||||
|
||||
if ((rv = nng_msg_alloc(&msg, 0)) != 0) {
|
||||
fatal("nng_msg_alloc", rv);
|
||||
}
|
||||
if ((rv = nng_msg_append_u32(msg, msec)) != 0) {
|
||||
fatal("nng_msg_append_u32", rv);
|
||||
}
|
||||
|
||||
if ((rv = nng_sendmsg(sock, msg, 0)) != 0) {
|
||||
fatal("nng_send", rv);
|
||||
}
|
||||
|
||||
if ((rv = nng_recvmsg(sock, &msg, 0)) != 0) {
|
||||
fatal("nng_recvmsg", rv);
|
||||
}
|
||||
end = nng_clock();
|
||||
nng_msg_free(msg);
|
||||
nng_close(sock);
|
||||
|
||||
printf("Request took %u milliseconds.\n", (uint32_t)(end - start));
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "Usage: %s <url> [-s|<secs>]\n", argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (strcmp(argv[2], "-s") == 0) {
|
||||
rc = server(argv[1]);
|
||||
} else {
|
||||
rc = client(argv[1], argv[2]);
|
||||
}
|
||||
exit(rc == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
|
||||
}
|
22
external/nng/demo/reqrep/CMakeLists.txt
vendored
Normal file
22
external/nng/demo/reqrep/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
#
|
||||
# Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||||
# Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
|
||||
#
|
||||
# This software 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.
|
||||
|
||||
cmake_minimum_required (VERSION 2.8.7)
|
||||
|
||||
project(reqrep)
|
||||
|
||||
find_package(nng CONFIG REQUIRED)
|
||||
|
||||
find_package(Threads)
|
||||
|
||||
# Uncomment to enable ZeroTier transport
|
||||
# find_package(zerotiercore)
|
||||
|
||||
add_executable(reqrep reqrep.c)
|
||||
target_link_libraries(reqrep nng::nng)
|
59
external/nng/demo/reqrep/README.adoc
vendored
Normal file
59
external/nng/demo/reqrep/README.adoc
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
= reqrep
|
||||
|
||||
This is a very simple RPC service using the REQ/REP method.
|
||||
It is derived in part from Tim Dysinger's
|
||||
http://nanomsg.org/gettingstarted/[Getting Started With Nanomsg]
|
||||
examples, but we have updated for _nng_, and converted to use binary
|
||||
frames across the wire instead of string data.
|
||||
|
||||
The protocol is simple:
|
||||
|
||||
* Client will send a 64-bit command (network byte order, i.e. big endian).
|
||||
* Server sends a 64-bit response (also network byte order.)
|
||||
|
||||
The only command is "DATE", which has value 0x1. The value returned is
|
||||
a UNIX timestamp (seconds since Jan 1, 1970.)
|
||||
|
||||
(We used 64-bit values for simplicity, and to avoid the Y2038 bug when
|
||||
compiled on 64-bit systems.)
|
||||
|
||||
== Compiling
|
||||
|
||||
CMake with ninja-build is simplest:
|
||||
|
||||
[source, bash]
|
||||
----
|
||||
% mkdir build
|
||||
% cd build
|
||||
% cmake -G Ninja ..
|
||||
% ninja
|
||||
----
|
||||
|
||||
Or if you prefer a traditional approach,
|
||||
the following is an example typical of UNIX and similar systems like
|
||||
Linux and macOS may appeal:
|
||||
|
||||
[source, bash]
|
||||
----
|
||||
% export CPPFLAGS="-I /usr/local/include"
|
||||
% export LDFLAGS="-L /usr/local/lib -lnng"
|
||||
% export CC="cc"
|
||||
% ${CC} ${CPPFLAGS} reqrep.c -o reqrep ${LDFLAGS}
|
||||
----
|
||||
|
||||
== Running
|
||||
|
||||
You can run either the client or the server, and use whatever legal
|
||||
_nng_ URL you like:
|
||||
|
||||
[source, bash]
|
||||
----
|
||||
% ./reqrep server tcp://127.0.0.1:8899 &
|
||||
% ./reqrep client tcp://127.0.0.1:8899
|
||||
CLIENT: SENDING DATE REQUEST
|
||||
SERVER: RECEIVED DATE REQUEST
|
||||
SERVER: SENDING DATE: Thu Feb 8 10:26:18 2018
|
||||
CLIENT: RECEIVED DATE: Thu Feb 8 10:26:18 2018
|
||||
----
|
||||
|
||||
|
216
external/nng/demo/reqrep/reqrep.c
vendored
Normal file
216
external/nng/demo/reqrep/reqrep.c
vendored
Normal file
|
@ -0,0 +1,216 @@
|
|||
//
|
||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
|
||||
// Copyright 2021 Capitar IT Group BV <info@capitar.com>
|
||||
//
|
||||
// This software 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.
|
||||
//
|
||||
|
||||
//
|
||||
// This is just a simple REQ/REP demonstration application. It is derived
|
||||
// from the legacy nanomsg demonstration program of the same name, written
|
||||
// by Tim Dysinger, but updated for nng. I've also updated it to pass simpler
|
||||
// binary data rather than strings over the network.
|
||||
//
|
||||
// The program implements a simple RPC style service, which just returns
|
||||
// the date in UNIX time (seconds since 1970).
|
||||
//
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <nng/nng.h>
|
||||
#include <nng/protocol/reqrep0/rep.h>
|
||||
#include <nng/protocol/reqrep0/req.h>
|
||||
#include <nng/transport/zerotier/zerotier.h>
|
||||
#include <nng/supplemental/util/platform.h>
|
||||
|
||||
#define CLIENT "client"
|
||||
#define SERVER "server"
|
||||
#define DATECMD 1
|
||||
|
||||
#define PUT64(ptr, u) \
|
||||
do { \
|
||||
(ptr)[0] = (uint8_t)(((uint64_t)(u)) >> 56); \
|
||||
(ptr)[1] = (uint8_t)(((uint64_t)(u)) >> 48); \
|
||||
(ptr)[2] = (uint8_t)(((uint64_t)(u)) >> 40); \
|
||||
(ptr)[3] = (uint8_t)(((uint64_t)(u)) >> 32); \
|
||||
(ptr)[4] = (uint8_t)(((uint64_t)(u)) >> 24); \
|
||||
(ptr)[5] = (uint8_t)(((uint64_t)(u)) >> 16); \
|
||||
(ptr)[6] = (uint8_t)(((uint64_t)(u)) >> 8); \
|
||||
(ptr)[7] = (uint8_t)((uint64_t)(u)); \
|
||||
} while (0)
|
||||
|
||||
#define GET64(ptr, v) \
|
||||
v = (((uint64_t)((uint8_t)(ptr)[0])) << 56) + \
|
||||
(((uint64_t)((uint8_t)(ptr)[1])) << 48) + \
|
||||
(((uint64_t)((uint8_t)(ptr)[2])) << 40) + \
|
||||
(((uint64_t)((uint8_t)(ptr)[3])) << 32) + \
|
||||
(((uint64_t)((uint8_t)(ptr)[4])) << 24) + \
|
||||
(((uint64_t)((uint8_t)(ptr)[5])) << 16) + \
|
||||
(((uint64_t)((uint8_t)(ptr)[6])) << 8) + \
|
||||
(((uint64_t)(uint8_t)(ptr)[7]))
|
||||
|
||||
void
|
||||
fatal(const char *func, int rv)
|
||||
{
|
||||
fprintf(stderr, "%s: %s\n", func, nng_strerror(rv));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void
|
||||
showdate(time_t now)
|
||||
{
|
||||
struct tm *info = localtime(&now);
|
||||
printf("%s", asctime(info));
|
||||
}
|
||||
|
||||
int
|
||||
server(const char *url)
|
||||
{
|
||||
nng_socket sock;
|
||||
nng_listener listener;
|
||||
int rv;
|
||||
int count = 0;
|
||||
|
||||
if ((rv = nng_rep0_open(&sock)) != 0) {
|
||||
fatal("nng_rep0_open", rv);
|
||||
}
|
||||
|
||||
if ((rv = nng_listener_create(&listener, sock, url)) != 0) {
|
||||
fatal("nng_listener_create", rv);
|
||||
}
|
||||
|
||||
if (strncmp(url, "zt://", 5) == 0) {
|
||||
printf("ZeroTier transport will store its keys in current working directory.\n");
|
||||
printf("The server and client instances must run in separate directories.\n");
|
||||
nng_listener_setopt_string(listener, NNG_OPT_ZT_HOME, ".");
|
||||
nng_listener_setopt_ms(listener, NNG_OPT_RECONNMINT, 1);
|
||||
nng_listener_setopt_ms(listener, NNG_OPT_RECONNMAXT, 1000);
|
||||
nng_setopt_ms(sock, NNG_OPT_REQ_RESENDTIME, 2000);
|
||||
nng_setopt_ms(sock, NNG_OPT_RECVMAXSZ, 0);
|
||||
nng_listener_setopt_ms(listener, NNG_OPT_ZT_PING_TIME, 10000);
|
||||
nng_listener_setopt_ms(listener, NNG_OPT_ZT_CONN_TIME, 1000);
|
||||
} else {
|
||||
nng_setopt_ms(sock, NNG_OPT_REQ_RESENDTIME, 2000);
|
||||
}
|
||||
nng_listener_start(listener, 0);
|
||||
|
||||
for (;;) {
|
||||
char * buf = NULL;
|
||||
size_t sz;
|
||||
uint64_t val;
|
||||
count++;
|
||||
if ((rv = nng_recv(sock, &buf, &sz, NNG_FLAG_ALLOC)) != 0) {
|
||||
fatal("nng_recv", rv);
|
||||
}
|
||||
if ((sz == sizeof(uint64_t)) &&
|
||||
((GET64(buf, val)) == DATECMD)) {
|
||||
time_t now;
|
||||
printf("SERVER: RECEIVED DATE REQUEST\n");
|
||||
now = time(&now);
|
||||
if (count == 6) {
|
||||
printf("SERVER: SKIP SENDING REPLY\n");
|
||||
nng_free(buf, sz);
|
||||
continue;
|
||||
}
|
||||
printf("SERVER: SENDING DATE: ");
|
||||
showdate(now);
|
||||
|
||||
// Reuse the buffer. We know it is big enough.
|
||||
PUT64(buf, (uint64_t) now);
|
||||
rv = nng_send(sock, buf, sz, NNG_FLAG_ALLOC);
|
||||
if (rv != 0) {
|
||||
fatal("nng_send", rv);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// Unrecognized command, so toss the buffer.
|
||||
nng_free(buf, sz);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
client(const char *url)
|
||||
{
|
||||
nng_socket sock;
|
||||
nng_dialer dialer;
|
||||
int rv;
|
||||
size_t sz;
|
||||
char * buf = NULL;
|
||||
uint8_t cmd[sizeof(uint64_t)];
|
||||
int sleep = 0;
|
||||
|
||||
PUT64(cmd, DATECMD);
|
||||
|
||||
if ((rv = nng_req0_open(&sock)) != 0) {
|
||||
fatal("nng_socket", rv);
|
||||
}
|
||||
|
||||
if ((rv = nng_dialer_create(&dialer, sock, url)) != 0) {
|
||||
fatal("nng_dialer_create", rv);
|
||||
}
|
||||
|
||||
if (strncmp(url, "zt://", 5) == 0) {
|
||||
printf("ZeroTier transport will store its keys in current working directory\n");
|
||||
printf("The server and client instances must run in separate directories.\n");
|
||||
nng_dialer_setopt_string(dialer, NNG_OPT_ZT_HOME, ".");
|
||||
nng_dialer_setopt_ms(dialer, NNG_OPT_RECONNMINT, 1);
|
||||
nng_dialer_setopt_ms(dialer, NNG_OPT_RECONNMAXT, 1000);
|
||||
nng_setopt_ms(sock, NNG_OPT_REQ_RESENDTIME, 2000);
|
||||
nng_setopt_ms(sock, NNG_OPT_RECVMAXSZ, 0);
|
||||
nng_dialer_setopt_ms(dialer, NNG_OPT_ZT_PING_TIME, 10000);
|
||||
nng_dialer_setopt_ms(dialer, NNG_OPT_ZT_CONN_TIME, 1000);
|
||||
} else {
|
||||
nng_setopt_ms(sock, NNG_OPT_REQ_RESENDTIME, 2000);
|
||||
}
|
||||
|
||||
nng_dialer_start(dialer, NNG_FLAG_NONBLOCK);
|
||||
|
||||
while (1) {
|
||||
|
||||
printf("CLIENT: SENDING DATE REQUEST\n");
|
||||
if ((rv = nng_send(sock, cmd, sizeof(cmd), 0)) != 0) {
|
||||
fatal("nng_send", rv);
|
||||
}
|
||||
if ((rv = nng_recv(sock, &buf, &sz, NNG_FLAG_ALLOC)) != 0) {
|
||||
fatal("nng_recv", rv);
|
||||
}
|
||||
|
||||
if (sz == sizeof(uint64_t)) {
|
||||
uint64_t now;
|
||||
GET64(buf, now);
|
||||
printf("CLIENT: RECEIVED DATE: ");
|
||||
showdate((time_t) now);
|
||||
} else {
|
||||
printf("CLIENT: GOT WRONG SIZE!\n");
|
||||
}
|
||||
nng_msleep(sleep);
|
||||
sleep++;
|
||||
if (sleep == 4) {
|
||||
sleep = 4000;
|
||||
}
|
||||
}
|
||||
|
||||
// This assumes that buf is ASCIIZ (zero terminated).
|
||||
nng_free(buf, sz);
|
||||
nng_close(sock);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
main(const int argc, const char **argv)
|
||||
{
|
||||
if ((argc > 1) && (strcmp(CLIENT, argv[1]) == 0))
|
||||
return (client(argv[2]));
|
||||
|
||||
if ((argc > 1) && (strcmp(SERVER, argv[1]) == 0))
|
||||
return (server(argv[2]));
|
||||
|
||||
fprintf(stderr, "Usage: reqrep %s|%s <URL> ...\n", CLIENT, SERVER);
|
||||
return (1);
|
||||
}
|
17
external/nng/demo/rest/CMakeLists.txt
vendored
Normal file
17
external/nng/demo/rest/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
#
|
||||
# Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||||
# Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
|
||||
#
|
||||
# This software 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.
|
||||
|
||||
cmake_minimum_required (VERSION 2.8.7)
|
||||
|
||||
project(rest)
|
||||
|
||||
find_package(nng CONFIG REQUIRED)
|
||||
|
||||
add_executable(rest-server server.c)
|
||||
target_link_libraries(rest-server nng::nng)
|
45
external/nng/demo/rest/README.adoc
vendored
Normal file
45
external/nng/demo/rest/README.adoc
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
= REST API Gateway demo
|
||||
|
||||
This is a somewhat contrived demonstration, but may be useful
|
||||
in a pattern for solving real world problems.
|
||||
|
||||
There is a single "server" (rest-server) program, that does these:
|
||||
|
||||
. REST API at /api/rest/rot13 - this API takes data from HTTP POST commands,
|
||||
and forwards them to an NNG REQ socket. When the REQ response comes,
|
||||
the reply is redirected back to the server. (For the purposes of the
|
||||
demonstration, our server just performs ROT13 on input.)
|
||||
|
||||
. REP server (implemented in the same program using inproc, for demonstration
|
||||
purposes. In a real world scenario this might instead go to another
|
||||
process on another computer.)
|
||||
|
||||
[source, bash]
|
||||
----
|
||||
% env PORT=8888 # default
|
||||
% ./rest-server &
|
||||
% curl -d ABC http://127.0.0.1:8888/api/rest/rot13; echo
|
||||
NOP
|
||||
% curl -d ABC http://127.0.0.1:8888/api/rest/rot13; echo
|
||||
ABC
|
||||
----
|
||||
|
||||
== Compiling
|
||||
|
||||
To build the program, we recommend CMake and Ninja-Build.
|
||||
|
||||
[source, bash]
|
||||
----
|
||||
% mkdir build
|
||||
% cd build
|
||||
% cmake -G Ninja ..
|
||||
% ninja
|
||||
----
|
||||
|
||||
Alternatively, you can go old-school.
|
||||
Here's the simplest option for Linux:
|
||||
|
||||
[source, bash]
|
||||
----
|
||||
% cc server.c -o rest-server -I /usr/local/include -lnng
|
||||
----
|
372
external/nng/demo/rest/server.c
vendored
Normal file
372
external/nng/demo/rest/server.c
vendored
Normal file
|
@ -0,0 +1,372 @@
|
|||
//
|
||||
// Copyright 2018 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
|
||||
// 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.
|
||||
//
|
||||
|
||||
#define INPROC_URL "inproc://rot13"
|
||||
#define REST_URL "http://127.0.0.1:%u/api/rest/rot13"
|
||||
|
||||
// REST API -> NNG REP server demonstration.
|
||||
|
||||
// This is a silly demo -- it listens on port 8888 (or $PORT if present),
|
||||
// and accepts HTTP POST requests at /api/rest/rot13
|
||||
//
|
||||
// These requests are converted into an NNG REQ message, and sent to an
|
||||
// NNG REP server (builtin inproc_server, for demonstration purposes only).
|
||||
// The reply is obtained from the server, and sent back to the client via
|
||||
// the HTTP server framework.
|
||||
|
||||
// Example usage:
|
||||
//
|
||||
// % export CPPFLAGS="-I /usr/local/include"
|
||||
// % export LDFLAGS="-L /usr/local/lib -lnng"
|
||||
// % export CC="cc"
|
||||
// % ${CC} ${CPPFLAGS} server.c -o server ${LDFLAGS}
|
||||
// % ./server &
|
||||
// % curl -d TEST http://127.0.0.1:8888/api/rest/rot13
|
||||
// GRFG
|
||||
//
|
||||
|
||||
#include <nng/nng.h>
|
||||
#include <nng/protocol/reqrep0/rep.h>
|
||||
#include <nng/protocol/reqrep0/req.h>
|
||||
#include <nng/supplemental/http/http.h>
|
||||
#include <nng/supplemental/util/platform.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// utility function
|
||||
void
|
||||
fatal(const char *what, int rv)
|
||||
{
|
||||
fprintf(stderr, "%s: %s\n", what, nng_strerror(rv));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// This server acts as a proxy. We take HTTP POST requests, convert them to
|
||||
// REQ messages, and when the reply is received, send the reply back to
|
||||
// the original HTTP client.
|
||||
//
|
||||
// The state flow looks like:
|
||||
//
|
||||
// 1. Receive HTTP request & headers
|
||||
// 2. Receive HTTP request (POST) data
|
||||
// 3. Send POST payload as REQ body
|
||||
// 4. Receive REP reply (including payload)
|
||||
// 5. Return REP message body to the HTTP server (which forwards to client)
|
||||
// 6. Restart at step 1.
|
||||
//
|
||||
// The above flow is pretty linear, and so we use contexts (nng_ctx) to
|
||||
// obtain parallelism.
|
||||
|
||||
typedef enum {
|
||||
SEND_REQ, // Sending REQ request
|
||||
RECV_REP, // Receiving REQ reply
|
||||
} job_state;
|
||||
|
||||
typedef struct rest_job {
|
||||
nng_aio * http_aio; // aio from HTTP we must reply to
|
||||
nng_http_res * http_res; // HTTP response object
|
||||
job_state state; // 0 = sending, 1 = receiving
|
||||
nng_msg * msg; // request message
|
||||
nng_aio * aio; // request flow
|
||||
nng_ctx ctx; // context on the request socket
|
||||
struct rest_job *next; // next on the freelist
|
||||
} rest_job;
|
||||
|
||||
nng_socket req_sock;
|
||||
|
||||
// We maintain a queue of free jobs. This way we don't have to
|
||||
// deallocate them from the callback; we just reuse them.
|
||||
nng_mtx * job_lock;
|
||||
rest_job *job_freelist;
|
||||
|
||||
static void rest_job_cb(void *arg);
|
||||
|
||||
static void
|
||||
rest_recycle_job(rest_job *job)
|
||||
{
|
||||
if (job->http_res != NULL) {
|
||||
nng_http_res_free(job->http_res);
|
||||
job->http_res = NULL;
|
||||
}
|
||||
if (job->msg != NULL) {
|
||||
nng_msg_free(job->msg);
|
||||
job->msg = NULL;
|
||||
}
|
||||
if (nng_ctx_id(job->ctx) != 0) {
|
||||
nng_ctx_close(job->ctx);
|
||||
}
|
||||
|
||||
nng_mtx_lock(job_lock);
|
||||
job->next = job_freelist;
|
||||
job_freelist = job;
|
||||
nng_mtx_unlock(job_lock);
|
||||
}
|
||||
|
||||
static rest_job *
|
||||
rest_get_job(void)
|
||||
{
|
||||
rest_job *job;
|
||||
|
||||
nng_mtx_lock(job_lock);
|
||||
if ((job = job_freelist) != NULL) {
|
||||
job_freelist = job->next;
|
||||
nng_mtx_unlock(job_lock);
|
||||
job->next = NULL;
|
||||
return (job);
|
||||
}
|
||||
nng_mtx_unlock(job_lock);
|
||||
if ((job = calloc(1, sizeof(*job))) == NULL) {
|
||||
return (NULL);
|
||||
}
|
||||
if (nng_aio_alloc(&job->aio, rest_job_cb, job) != 0) {
|
||||
free(job);
|
||||
return (NULL);
|
||||
}
|
||||
return (job);
|
||||
}
|
||||
|
||||
static void
|
||||
rest_http_fatal(rest_job *job, const char *fmt, int rv)
|
||||
{
|
||||
char buf[128];
|
||||
nng_aio * aio = job->http_aio;
|
||||
nng_http_res *res = job->http_res;
|
||||
|
||||
job->http_res = NULL;
|
||||
job->http_aio = NULL;
|
||||
snprintf(buf, sizeof(buf), fmt, nng_strerror(rv));
|
||||
nng_http_res_set_status(res, NNG_HTTP_STATUS_INTERNAL_SERVER_ERROR);
|
||||
nng_http_res_set_reason(res, buf);
|
||||
nng_aio_set_output(aio, 0, res);
|
||||
nng_aio_finish(aio, 0);
|
||||
rest_recycle_job(job);
|
||||
}
|
||||
|
||||
static void
|
||||
rest_job_cb(void *arg)
|
||||
{
|
||||
rest_job *job = arg;
|
||||
nng_aio * aio = job->aio;
|
||||
int rv;
|
||||
|
||||
switch (job->state) {
|
||||
case SEND_REQ:
|
||||
if ((rv = nng_aio_result(aio)) != 0) {
|
||||
rest_http_fatal(job, "send REQ failed: %s", rv);
|
||||
return;
|
||||
}
|
||||
job->msg = NULL;
|
||||
// Message was sent, so now wait for the reply.
|
||||
nng_aio_set_msg(aio, NULL);
|
||||
job->state = RECV_REP;
|
||||
nng_ctx_recv(job->ctx, aio);
|
||||
break;
|
||||
case RECV_REP:
|
||||
if ((rv = nng_aio_result(aio)) != 0) {
|
||||
rest_http_fatal(job, "recv reply failed: %s", rv);
|
||||
return;
|
||||
}
|
||||
job->msg = nng_aio_get_msg(aio);
|
||||
// We got a reply, so give it back to the server.
|
||||
rv = nng_http_res_copy_data(job->http_res,
|
||||
nng_msg_body(job->msg), nng_msg_len(job->msg));
|
||||
if (rv != 0) {
|
||||
rest_http_fatal(job, "nng_http_res_copy_data: %s", rv);
|
||||
return;
|
||||
}
|
||||
// Set the output - the HTTP server will send it back to the
|
||||
// user agent with a 200 response.
|
||||
nng_aio_set_output(job->http_aio, 0, job->http_res);
|
||||
nng_aio_finish(job->http_aio, 0);
|
||||
job->http_aio = NULL;
|
||||
job->http_res = NULL;
|
||||
// We are done with the job.
|
||||
rest_recycle_job(job);
|
||||
return;
|
||||
default:
|
||||
fatal("bad case", NNG_ESTATE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Our rest server just takes the message body, creates a request ID
|
||||
// for it, and sends it on. This runs in raw mode, so
|
||||
void
|
||||
rest_handle(nng_aio *aio)
|
||||
{
|
||||
struct rest_job *job;
|
||||
nng_http_req * req = nng_aio_get_input(aio, 0);
|
||||
nng_http_conn * conn = nng_aio_get_input(aio, 2);
|
||||
const char * clen;
|
||||
size_t sz;
|
||||
nng_iov iov;
|
||||
int rv;
|
||||
void * data;
|
||||
|
||||
if ((job = rest_get_job()) == NULL) {
|
||||
nng_aio_finish(aio, NNG_ENOMEM);
|
||||
return;
|
||||
}
|
||||
if (((rv = nng_http_res_alloc(&job->http_res)) != 0) ||
|
||||
((rv = nng_ctx_open(&job->ctx, req_sock)) != 0)) {
|
||||
rest_recycle_job(job);
|
||||
nng_aio_finish(aio, rv);
|
||||
return;
|
||||
}
|
||||
|
||||
nng_http_req_get_data(req, &data, &sz);
|
||||
job->http_aio = aio;
|
||||
|
||||
if ((rv = nng_msg_alloc(&job->msg, sz)) != 0) {
|
||||
rest_http_fatal(job, "nng_msg_alloc: %s", rv);
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(nng_msg_body(job->msg), data, sz);
|
||||
nng_aio_set_msg(job->aio, job->msg);
|
||||
job->state = SEND_REQ;
|
||||
nng_ctx_send(job->ctx, job->aio);
|
||||
}
|
||||
|
||||
void
|
||||
rest_start(uint16_t port)
|
||||
{
|
||||
nng_http_server * server;
|
||||
nng_http_handler *handler;
|
||||
char rest_addr[128];
|
||||
nng_url * url;
|
||||
int rv;
|
||||
|
||||
if ((rv = nng_mtx_alloc(&job_lock)) != 0) {
|
||||
fatal("nng_mtx_alloc", rv);
|
||||
}
|
||||
job_freelist = NULL;
|
||||
|
||||
// Set up some strings, etc. We use the port number
|
||||
// from the argument list.
|
||||
snprintf(rest_addr, sizeof(rest_addr), REST_URL, port);
|
||||
if ((rv = nng_url_parse(&url, rest_addr)) != 0) {
|
||||
fatal("nng_url_parse", rv);
|
||||
}
|
||||
|
||||
// Create the REQ socket, and put it in raw mode, connected to
|
||||
// the remote REP server (our inproc server in this case).
|
||||
if ((rv = nng_req0_open(&req_sock)) != 0) {
|
||||
fatal("nng_req0_open", rv);
|
||||
}
|
||||
if ((rv = nng_dial(req_sock, INPROC_URL, NULL, NNG_FLAG_NONBLOCK)) !=
|
||||
0) {
|
||||
fatal("nng_dial(" INPROC_URL ")", rv);
|
||||
}
|
||||
|
||||
// Get a suitable HTTP server instance. This creates one
|
||||
// if it doesn't already exist.
|
||||
if ((rv = nng_http_server_hold(&server, url)) != 0) {
|
||||
fatal("nng_http_server_hold", rv);
|
||||
}
|
||||
|
||||
// Allocate the handler - we use a dynamic handler for REST
|
||||
// using the function "rest_handle" declared above.
|
||||
rv = nng_http_handler_alloc(&handler, url->u_path, rest_handle);
|
||||
if (rv != 0) {
|
||||
fatal("nng_http_handler_alloc", rv);
|
||||
}
|
||||
|
||||
if ((rv = nng_http_handler_set_method(handler, "POST")) != 0) {
|
||||
fatal("nng_http_handler_set_method", rv);
|
||||
}
|
||||
// We want to collect the body, and we (arbitrarily) limit this to
|
||||
// 128KB. The default limit is 1MB. You can explicitly collect
|
||||
// the data yourself with another HTTP read transaction by disabling
|
||||
// this, but that's a lot of work, especially if you want to handle
|
||||
// chunked transfers.
|
||||
if ((rv = nng_http_handler_collect_body(handler, true, 1024 * 128)) !=
|
||||
0) {
|
||||
fatal("nng_http_handler_collect_body", rv);
|
||||
}
|
||||
if ((rv = nng_http_server_add_handler(server, handler)) != 0) {
|
||||
fatal("nng_http_handler_add_handler", rv);
|
||||
}
|
||||
if ((rv = nng_http_server_start(server)) != 0) {
|
||||
fatal("nng_http_server_start", rv);
|
||||
}
|
||||
|
||||
nng_url_free(url);
|
||||
}
|
||||
|
||||
//
|
||||
// inproc_server - this just is a simple REP server that listens for
|
||||
// messages, and performs ROT13 on them before sending them. This
|
||||
// doesn't have to be in the same process -- it is hear for demonstration
|
||||
// simplicity only. (Most likely this would be somewhere else.) Note
|
||||
// especially that this uses inproc, so nothing can get to it directly
|
||||
// from outside the process.
|
||||
//
|
||||
void
|
||||
inproc_server(void *arg)
|
||||
{
|
||||
nng_socket s;
|
||||
int rv;
|
||||
nng_msg * msg;
|
||||
|
||||
if (((rv = nng_rep0_open(&s)) != 0) ||
|
||||
((rv = nng_listen(s, INPROC_URL, NULL, 0)) != 0)) {
|
||||
fatal("unable to set up inproc", rv);
|
||||
}
|
||||
// This is simple enough that we don't need concurrency. Plus it
|
||||
// makes for an easier demo.
|
||||
for (;;) {
|
||||
char *body;
|
||||
if ((rv = nng_recvmsg(s, &msg, 0)) != 0) {
|
||||
fatal("inproc recvmsg", rv);
|
||||
}
|
||||
body = nng_msg_body(msg);
|
||||
for (int i = 0; i < nng_msg_len(msg); i++) {
|
||||
// Table lookup would be faster, but this works.
|
||||
if (isupper(body[i])) {
|
||||
char base = body[i] - 'A';
|
||||
base = (base + 13) % 26;
|
||||
body[i] = base + 'A';
|
||||
} else if (islower(body[i])) {
|
||||
char base = body[i] - 'a';
|
||||
base = (base + 13) % 26;
|
||||
body[i] = base + 'a';
|
||||
}
|
||||
}
|
||||
if ((rv = nng_sendmsg(s, msg, 0)) != 0) {
|
||||
fatal("inproc sendmsg", rv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int rv;
|
||||
nng_thread *inproc_thr;
|
||||
uint16_t port = 0;
|
||||
|
||||
rv = nng_thread_create(&inproc_thr, inproc_server, NULL);
|
||||
if (rv != 0) {
|
||||
fatal("cannot start inproc server", rv);
|
||||
}
|
||||
if (getenv("PORT") != NULL) {
|
||||
port = (uint16_t) atoi(getenv("PORT"));
|
||||
}
|
||||
port = port ? port : 8888;
|
||||
rest_start(port);
|
||||
|
||||
// This runs forever. The inproc_thr never exits, so we
|
||||
// just block behind its condition variable.
|
||||
nng_thread_destroy(inproc_thr);
|
||||
}
|
84
external/nng/docs/BUILD_ANDROID.adoc
vendored
Normal file
84
external/nng/docs/BUILD_ANDROID.adoc
vendored
Normal file
|
@ -0,0 +1,84 @@
|
|||
ifdef::env-github[]
|
||||
:note-caption: :information_source:
|
||||
endif::[]
|
||||
|
||||
= Building for Android
|
||||
|
||||
NOTE: This work has received only cursory testing. As always, _caveat emptor_.
|
||||
|
||||
== Pre-Requisites
|
||||
|
||||
Android Studio:::
|
||||
|
||||
There are probably other ways to cross-build for Android, but if you're
|
||||
not using Android Studio, then you probably don't need much help here.
|
||||
|
||||
Android NDK::
|
||||
|
||||
A copy of the Android NDK is required to build native code applications.
|
||||
Android Studio has information for downloading it within the app.
|
||||
|
||||
== Steps
|
||||
|
||||
You need to use the CMake that is included with Android Studio, because
|
||||
it knows how to build the Gradle targets. (At least on macOS, the system
|
||||
default cmake does not have the right generator support.)
|
||||
|
||||
You will also use the Android toolchain file for CMake that is included
|
||||
with the NDK.
|
||||
|
||||
NOTE: You *must* use the _NDK_ toolchain, not the one that came with the _SDK_.
|
||||
The _SDK_ toolchain file is too old and will not work with modern NDKs!
|
||||
|
||||
When building for Android, by default we build static libraries, and
|
||||
we do not build tools or tests. The tools and tests won't work since
|
||||
they assume a shell environment, and you don't want to deal with the
|
||||
dependency nightmare that is dynamic libraries anyway. Trust us.
|
||||
|
||||
The Android NDK includes documentation for how to run
|
||||
CMake including the options that can be set. Details are located
|
||||
here: https://developer.android.com/ndk/guides/cmake
|
||||
|
||||
TIP: It is *highly* recommended you review the NDK documentation,
|
||||
because you will most likely want to change some of the default values
|
||||
for the ABI or API level.
|
||||
For the sake of clarity, we are assuming only the defaults here.
|
||||
|
||||
Set the following environment variables:
|
||||
|
||||
`CMAKE`::
|
||||
|
||||
Path to the Android SDK supplied CMake binary. For example, on
|
||||
our macOS install of Android Studio, we have it located in
|
||||
`$HOME/Library/Android/sdk/cmake/3.6.4111459/bin/cmake`.
|
||||
|
||||
`NDK`::
|
||||
|
||||
Path to the Android NDK. In the same installation, on our system,
|
||||
it is in `$HOME/Library/Android/sdk/ndk-bundle`
|
||||
|
||||
Using the above toolchain file, we can build for Android using
|
||||
the CMake standard `CMAKE_TOOLCHAIN_FILE` macro, and using the
|
||||
Android supplied CMake:
|
||||
|
||||
If you have checked out this repository in `$SRC`, and your copy of the
|
||||
Android SDK is located in `$SDK`, the following should work:
|
||||
|
||||
[source, sh]
|
||||
----
|
||||
% cd $SRC
|
||||
% mkdir android-build
|
||||
% cd android-build
|
||||
% ${CMAKE} -DCMAKE_TOOLCHAIN_FILE=${NDK}/build/cmake/android.toolchain.cmake ..
|
||||
----
|
||||
|
||||
Then you can build using Xcode, or simply use cmake to drive the build:
|
||||
|
||||
[source, sh]
|
||||
----
|
||||
% ${CMAKE} --build .
|
||||
----
|
||||
|
||||
Extra effort may be required to enable the use of mbedTLS; you will
|
||||
need to review the mbedTLS documentation for configuring that for use
|
||||
in Android.
|
49
external/nng/docs/BUILD_CROSSCOMPILE.adoc
vendored
Normal file
49
external/nng/docs/BUILD_CROSSCOMPILE.adoc
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
ifdef::env-github[]
|
||||
:note-caption: :information_source:
|
||||
endif::[]
|
||||
|
||||
= Building for Cross Compilation
|
||||
|
||||
TIP: Cross-compiling is used when the operating system or process architecure
|
||||
the software is being built for is different than the system where the software
|
||||
is being compiled. If you don't know what this means, this does not apply to
|
||||
and you should ignore this file.
|
||||
|
||||
When building for cross-compilation, you can use CMake's native support
|
||||
`CMAKE_TOOLCHAIN_FILE` to configure the location of the toolchain.
|
||||
|
||||
You'll need that toolchain to have your compiler, linker, header files,
|
||||
and possibly any other libraries that need to be linked at build time.
|
||||
|
||||
This is all relatively standard stuff for CMake.
|
||||
|
||||
A lot more detail is located here: https://gitlab.kitware.com/cmake/community/wikis/doc/cmake/CrossCompiling
|
||||
|
||||
NOTE: When _NNG_ detects that it is being built in a Cross-Compile
|
||||
situation (i.e. when `CMAKE_CROSSCOMPILING` is true), it will default
|
||||
to disabling the building of the test suite and tools.
|
||||
This is normally preferable, since many embedded environments cannot host
|
||||
command line applications or shell environments. +
|
||||
+
|
||||
To enable tools or tests to build anyway, the values of either
|
||||
`NNG_TOOLS` or `NNG_TESTS` (or both) may be set to `ON`.
|
||||
|
||||
== Cross-compiling for Android
|
||||
|
||||
More details for Android are located in the <<BUILD_ANDROID.adoc>> file.
|
||||
|
||||
== Cross-compiling for iOS
|
||||
|
||||
More details for iOS (and tvOS, etc.) are located in the <<BUILD_IOS.adoc>> file.
|
||||
|
||||
== Cross-compiling for Windows or Linux or MACOS - Using vcpkg
|
||||
|
||||
You can download and install nng using the [vcpkg](https://github.com/Microsoft/vcpkg) dependency manager:
|
||||
|
||||
git clone https://github.com/Microsoft/vcpkg.git
|
||||
cd vcpkg
|
||||
./bootstrap-vcpkg.sh
|
||||
./vcpkg integrate install
|
||||
./vcpkg install nng
|
||||
|
||||
The nng port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
|
65
external/nng/docs/BUILD_IOS.adoc
vendored
Normal file
65
external/nng/docs/BUILD_IOS.adoc
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
ifdef::env-github[]
|
||||
:note-caption: :information_source:
|
||||
endif::[]
|
||||
|
||||
= Building for iOS (and tvOS, watchOS)
|
||||
|
||||
NOTE: This work has had only minimal validation. As always, _caveat emptor_.
|
||||
|
||||
== Pre-Requisites
|
||||
|
||||
macOS::
|
||||
|
||||
As far as we know, the only way to build iOS applications is on a
|
||||
macOS host system.
|
||||
|
||||
Xcode::
|
||||
|
||||
You will need Xcode. We tested this with Xcode 9.3.
|
||||
|
||||
CMake::
|
||||
|
||||
We tested this with CMake 3.9. Other versions may work.
|
||||
|
||||
iOS cmake toolchain file::
|
||||
|
||||
At the time of this writing (May 28, 2018), the toolchain file
|
||||
located at https://github.com/leetal/ios-cmake is appears to work
|
||||
reasonably well.
|
||||
|
||||
== Steps
|
||||
|
||||
When building for iOS and similar targets, only static libraries may be built.
|
||||
(This is good for avoiding dependency nightmares anyway.)
|
||||
|
||||
Using the above toolchain file, we can build for iOS using
|
||||
the CMake standard CMAKE_TOOLCHAIN_FILE macro, and using
|
||||
the IOS_PLATFORM macro to set the target. (See the iOS CMake
|
||||
toolchain README for valid options; we select "OS" for iOS.)
|
||||
|
||||
The test suite and command line tools will automatically be removed
|
||||
from the build, since they aren't interesting or useful in cross-compile
|
||||
environment. (There is no way to run them.)
|
||||
|
||||
If you have checked out this repository in $SRC, the following should work:
|
||||
|
||||
[source, sh]
|
||||
----
|
||||
% cd $SRC
|
||||
% mkdir ios-build
|
||||
% cd ios-build
|
||||
% git clone https://github.com/leetal/ios-cmake
|
||||
% cmake -G Xcode \
|
||||
-DCMAKE_TOOLCHAIN_FILE=`pwd`/ios-cmake/ios.toolchain.cmake \
|
||||
-DIOS_PLATFORM=OS ..
|
||||
----
|
||||
|
||||
Then you can build using Xcode, or simply use cmake to drive the build:
|
||||
|
||||
[source, sh]
|
||||
----
|
||||
% cmake --build .
|
||||
----
|
||||
|
||||
Extra effort may be required to enable the use of mbedTLS (NNG does not
|
||||
at the time of writing support Secure Transport. See issue #497 for status.)
|
60
external/nng/docs/BUILD_TLS.adoc
vendored
Normal file
60
external/nng/docs/BUILD_TLS.adoc
vendored
Normal file
|
@ -0,0 +1,60 @@
|
|||
ifdef::env-github[]
|
||||
:important-caption: :heavy_exclamation_mark:
|
||||
endif::[]
|
||||
|
||||
= Building for TLSv1.2 Support
|
||||
|
||||
If you want to include support for Transport Layer Security
|
||||
(tls+tcp:// and wss:// URLs) you should follow these directions.
|
||||
|
||||
At this time, TLS support depends on the mbedTLS library.
|
||||
See https://tls.mbed.org/ for details.
|
||||
|
||||
IMPORTANT: mbedTLS is licensed under different terms than NNG.
|
||||
You are responsible for reading those license terms, and ensuring
|
||||
that your use conforms to them.
|
||||
|
||||
On many distributions you may be able to install a pre-packaged version
|
||||
of mbedTLS. We recommend doing so if this is an option for you.
|
||||
For example, Ubuntu users can install the `libmbedtls-dev` package.
|
||||
|
||||
You can also build mbedTLS from source; if you choose to do so,
|
||||
please make sure you also *install* it somewhere (even a temporary
|
||||
staging directory).
|
||||
|
||||
== Configuring NNG with mbedTLS
|
||||
|
||||
TLS support is not enabled by default, but can be enabled by configuring
|
||||
with the CMake option `NNG_ENABLE_TLS=ON`.
|
||||
|
||||
By default NNG searches for an installed copy of mbedTLS in `/usr/local`,
|
||||
as well as the normal installation directories for libraries on your system.
|
||||
|
||||
If you have installed mbedTLS elsewhere, you can direct the NNG configuration
|
||||
to it by setting the `MBEDTLS_ROOT_DIR` CMake variable.
|
||||
|
||||
== Example
|
||||
|
||||
The following example would work on either Linux or macOS, and assumes
|
||||
that we have checked out github source trees into `$HOME/work`.
|
||||
It also assumes that mbedTLS is already installed in /usr/local or
|
||||
a standard search path.
|
||||
|
||||
[source, sh]
|
||||
----
|
||||
$ export NNGDIR=$HOME/work/nng
|
||||
$ mkdir build
|
||||
$ cd build
|
||||
|
||||
$ cmake -DNNG_ENABLE_TLS=ON ..
|
||||
|
||||
... (lots of lines of output from cmake...)
|
||||
|
||||
$ make
|
||||
|
||||
... (lots of lines of output from make...)
|
||||
|
||||
$ ./tests/tls
|
||||
ok ./tests/tls 1.503s
|
||||
|
||||
----
|
80
external/nng/docs/BUILD_ZEROTIER.adoc
vendored
Normal file
80
external/nng/docs/BUILD_ZEROTIER.adoc
vendored
Normal file
|
@ -0,0 +1,80 @@
|
|||
ifdef::env-github[]
|
||||
:important-caption: :heavy_exclamation_mark:
|
||||
endif::[]
|
||||
|
||||
= Building for ZeroTier Support
|
||||
|
||||
If you want to include support for the experimental ZeroTier
|
||||
transport (`zt://` URLs), you should follow these directions.
|
||||
|
||||
Staysail has created a package that builds a clean CMake project
|
||||
that you can import.
|
||||
Download this from https://github.com/staysail/libzerotiercore[GitHub].
|
||||
|
||||
|
||||
IMPORTANT: ZeroTierOne is licensed under different terms than NNG.
|
||||
You are responsible for reading those license terms, and ensuring that
|
||||
your use conforms to them.
|
||||
|
||||
IMPORTANT: The ZeroTier transport, and these build instructions,
|
||||
are experimental.
|
||||
We expect both to change over time as ZeroTier and the NNG `zt://` transport
|
||||
both mature.
|
||||
As always, _caveat emptor_.
|
||||
|
||||
== Building libzerotiercore
|
||||
|
||||
Using "CMake", you can build libzerotiercore
|
||||
using any normal CMake generator.
|
||||
You should install it as well.
|
||||
Normally it will install into `/usr/local` on
|
||||
Linux and UNIX systems.
|
||||
|
||||
== Configuring NNG with ZT
|
||||
|
||||
You will need to enable ZeroTier within NNG using the CMake option `NNG_TRANSPORT_ZEROTIER=ON`.
|
||||
If you have installed the libzerotiercore in
|
||||
one of the default locations, then that should be all
|
||||
that is needed.
|
||||
|
||||
If you have specified a different location, you will
|
||||
need to inform CMake of this by setting the CMake
|
||||
variable `-Dzerotier_DIR=<where you installed it>`
|
||||
|
||||
== Example
|
||||
|
||||
The following example would work on either Linux or macOS, and assumes
|
||||
that we have checked out github source trees into `$HOME/work`.
|
||||
|
||||
[source, sh]
|
||||
----
|
||||
$ export NNGDIR=$HOME/work/nng
|
||||
$ export ZTDIR=$HOME/work/libzerotiercore
|
||||
$ git clone https://github.com/staysail/libzerotiercore $ZTDIR
|
||||
$ cd $ZTDIR
|
||||
$ mkdir build
|
||||
$ cd build
|
||||
$ cmake ..
|
||||
|
||||
... (lots of lines of output from cmake...)
|
||||
|
||||
$ make
|
||||
|
||||
... (lots of lines of output from make...)
|
||||
|
||||
$ make install
|
||||
$ cd $NNGDIR
|
||||
$ mkdir build
|
||||
$ cd build
|
||||
$ cmake -DNNG_TRANSPORT_ZEROTIER=ON ..
|
||||
|
||||
... (lots of lines of output from cmake...)
|
||||
|
||||
$ make
|
||||
|
||||
... (lots of lines of output from make...)
|
||||
|
||||
$ ./tests/zt
|
||||
|
||||
ok ./tests/zt 22.837s
|
||||
----
|
129
external/nng/docs/CONTRIBUTING.adoc
vendored
Normal file
129
external/nng/docs/CONTRIBUTING.adoc
vendored
Normal file
|
@ -0,0 +1,129 @@
|
|||
= NNG Contributing Guidelines
|
||||
|
||||
Legal stuff:
|
||||
|
||||
For any submission you make to us, either by filing an issue, or submitting a
|
||||
defect, or sending us a message, you agree and certify that:
|
||||
|
||||
** You are the author or legal owner of the content submitted, or
|
||||
you have authorization to submit the content by the owner
|
||||
(such as your employer).
|
||||
|
||||
** Unless the submission is otherwise labeled, you or the owner
|
||||
are granting the NNG Project, its contributors, and licensees,
|
||||
a non-exclusive license to your use submission under the terms of
|
||||
MIT License (as documented in the <<LICENSE#,LICENSE>> file in this
|
||||
repository.) This grant shall include a right to use for any
|
||||
patents covering content in the submission.
|
||||
|
||||
** You are not aware of any legal encumbrances to the use of the
|
||||
submission (such as patents held by others) unless explicitly
|
||||
stated otherwise.
|
||||
|
||||
** You have read, and agree to abide by, our
|
||||
<<CODE_OF_CONDUCT#,Code of Conduct>>.
|
||||
|
||||
** You understand that participation in this project is voluntary,
|
||||
and at no point shall any of the project members or leadership
|
||||
be obligated to review, merge, or handle any submission.
|
||||
|
||||
== Filing Issues
|
||||
|
||||
We use github issues for NNG. We ask that you keep in mind the following
|
||||
when filing issues:
|
||||
|
||||
* First look to see if your issue is already covered by an existing issue.
|
||||
|
||||
* Synopsis should be brief, but descriptive. (We may alter the synopsis
|
||||
to correct its accuracy or improve its brevity.)
|
||||
|
||||
* Include details about the platform (operating system, language).
|
||||
|
||||
* Include CMake configuration used to build NNG.
|
||||
|
||||
* Include expected results or behavior, and observed results or behavior.
|
||||
|
||||
* If at all possible, a reproducible test case is helpful. We prefer test
|
||||
cases as the minimal amount of C code to demonstrate the defect.
|
||||
|
||||
* Please file issues only when filing things that should be fixed by
|
||||
changes to the source or documentation in the repository (such as bugs
|
||||
or feature requests). For support questions and other discussion, please
|
||||
instead use the mailing list
|
||||
https://www.freelists.org/list/nanomsg
|
||||
or Gitter chat
|
||||
https://gitter.im/nanomsg/nanomsg .
|
||||
|
||||
== Pull Requests
|
||||
|
||||
* We use Github PRs
|
||||
|
||||
* Please follow the existing coding style.
|
||||
|
||||
** See the `.clang-format` for whitespace rules.
|
||||
** Return values should be enclosed in parenthesis.
|
||||
** Conditional clauses are always enclosed in braces, and thus
|
||||
span multiple lines.
|
||||
|
||||
TIP: The `.clang-format` file and `clang-format` may be helpful, but
|
||||
is not necessarily complete. Also you may need to use a recent version
|
||||
of `clang-format` as older versions can differ in their output.
|
||||
|
||||
* If you submit a PR, we would appreciate it if you would respond to review
|
||||
feedback, rather than just leaving your baby on our doorstep. Abandoned
|
||||
PRs or issues may be closed without further action.
|
||||
|
||||
* Commits should have comments formatted like this:
|
||||
|
||||
----
|
||||
fixes #<issue#1> <issue#1-synopsis>
|
||||
fixes #<issue#2> <issue#2-synopsis>
|
||||
|
||||
<Comments describing the issues, or fix, that you want to have
|
||||
in the commit history. Not every issue needs such comments.>
|
||||
----
|
||||
|
||||
* We have an "always release ready" policy for our tree, meaning we should
|
||||
be able to build a functional release at any commit boundary. This ensures
|
||||
that others taking the work can use git bisect and similar approaches when
|
||||
hunting down regressions, or when cherry-picking changes for their own
|
||||
forked copies. This has a few consequences:
|
||||
|
||||
** PRs should be functionally complete (that is, don't submit a
|
||||
PR with partial work in progress, unless you have reached a
|
||||
milestone that can stand on its own merit.)
|
||||
|
||||
** Each commit in a PR should also be "complete", so that
|
||||
a release could be cut in between your commits without
|
||||
leaving the tree in a broken or dysfunctional state.
|
||||
|
||||
** Usually this means its best to address only one issue in a PR,
|
||||
with just one commit (squashed).
|
||||
|
||||
** Please have already merged and tested your code against the
|
||||
latest changes in master. (If your code has merge conflicts,
|
||||
your PR will be rejected until you have fixed the conflicts.)
|
||||
|
||||
* As a special exception, you may submit a PR for handling by our test
|
||||
infrastructure; in that case please clearly identify that the PR is
|
||||
submitted for that purpose, and should not considered for integration
|
||||
yet. When that testing is done, please close the PR, and submit a new
|
||||
one when you are ready for final review and integration.
|
||||
|
||||
* Code submitted should contain updates to any copyright files to add
|
||||
your copyright to the license. We prefer you follow the existing
|
||||
style of copyright, `// Copyright <year> <owner> <email or url>`
|
||||
|
||||
NOTE: We only use the most recent year, and we do not use `\(C)` which has
|
||||
no legal value when the word "`Copyright`" is already present. We also
|
||||
do not use the old "`All rights reserved.`" statement, which is equally
|
||||
meaningless under current international copyright law.
|
||||
|
||||
* When updating an existing file, any new Copyright notice should be
|
||||
added immediately below the pre-existing one, just before the license
|
||||
boilerplate.
|
||||
|
||||
* All new files should use the MIT license and the same boilerplate
|
||||
from one of the other files. We do not normally approve submissions
|
||||
with different license or boilerplates -- please contact us if you
|
||||
have a compelling reason for wanting to do that.
|
22
external/nng/docs/LICENSE.adoc
vendored
Normal file
22
external/nng/docs/LICENSE.adoc
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
= The MIT License
|
||||
|
||||
Copyright 2018 Staysail Systems, Inc. <info@staysail.tech> +
|
||||
Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom
|
||||
the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
IN THE SOFTWARE.
|
340
external/nng/docs/RATIONALE.adoc
vendored
Normal file
340
external/nng/docs/RATIONALE.adoc
vendored
Normal file
|
@ -0,0 +1,340 @@
|
|||
= Rationale: Or why am I bothering to rewrite nanomsg?
|
||||
Garrett D'Amore <garrett@damore.org>
|
||||
v0.3, April 10, 2018
|
||||
|
||||
|
||||
NOTE: You might want to review
|
||||
http://nanomsg.org/documentation-zeromq.html[Martin Sustrik's rationale]
|
||||
for nanomsg vs. ZeroMQ.
|
||||
|
||||
|
||||
== Background
|
||||
|
||||
I became involved in the
|
||||
http://www.nanomsg.org[nanomsg] community back in 2014, when
|
||||
I wrote https://github.com/go-mangos/mangos[mangos] as a pure
|
||||
http://www.golang.org[Go] implementation of the wire protocols behind
|
||||
_nanomsg_. I did that work because I was dissatisfied with the
|
||||
http://zeromq.org[_ZeroMQ_] licensing model
|
||||
and the {cpp} baggage that came with it. I also needed something that would
|
||||
work with _Go_ on http://www.illumos.org[illumos], which at the time
|
||||
lacked support for `cgo` (so I could not just use an FFI binding.)
|
||||
|
||||
|
||||
At the time, it was the only alternate implementation those protocols.
|
||||
Writing _mangos_ gave me a lot of detail about the internals of _nanomsg_ and
|
||||
the SP protocols.
|
||||
|
||||
It would not be wrong to say that one of the goals of _mangos_ was to teach
|
||||
me about _Go_. It was my first non-trivial _Go_ project.
|
||||
|
||||
While working with _mangos_, I wound up implementing a number of additional
|
||||
features, such as a TLS transport, the ability to bind to wild card ports,
|
||||
and the ability to determine more information about the sender of a message.
|
||||
This was incredibly useful in a number of projects.
|
||||
|
||||
I initially looked at _nanomsg_ itself, as I wanted to add a TLS transport
|
||||
to it, and I needed to make some bug fixes (for protocol bugs for example),
|
||||
and so forth.
|
||||
|
||||
== Lessons Learned
|
||||
|
||||
Perhaps it might be better to state that there were a number of opportunities
|
||||
to learn from the lessons of _nanomsg_, as well as lessons we learned while
|
||||
building _nng_ itself.
|
||||
|
||||
=== State Machine Madness
|
||||
|
||||
What I ran into in _nanomsg_, when attempting to improve it, was a
|
||||
challenging mess of state machines. _nanomsg_ has dozens of state machines,
|
||||
many of which feed into others, such that tracking flow through the state
|
||||
machines is incredibly painful.
|
||||
|
||||
Worse, these state machines are designed to be run from a single worker
|
||||
thread. This means that a given socket is entirely single theaded; you
|
||||
could in theory have dozens, hundreds, or even thousands of connections
|
||||
open, but they would be serviced only by a single thread. (Admittedly
|
||||
non-blocking I/O is used to let the OS kernel calls run asynchronously
|
||||
perhaps on multiple cores, but nanomsg itself runs all socket code on
|
||||
a single worker thread.)
|
||||
|
||||
There is another problem too -- the `inproc` code that moves messages
|
||||
between one socket and another was incredibly racy. This is because the
|
||||
two sockets have different locks, and so dealing with the different
|
||||
contexts was tricky (and consequently buggy). (I've since, I think, fixed
|
||||
the worst of the bugs here, but only after many hours of pulling out hair.)
|
||||
|
||||
The state machines also make fairly linear flow really difficult to follow.
|
||||
For example, there is a state machine to read the header information. This
|
||||
may come a byte a time, and the state machine has to add the bytes, check
|
||||
for completion, and possibly change state, even if it is just reading a
|
||||
single 32-bit word. This is a lot more complex than most programmers are
|
||||
used to, such as `read(fd, &val, 4)`.
|
||||
|
||||
Now to be fair, Martin Sustrik had the best intentions when he created the
|
||||
state machine model around which _nanomsg_ is built. I do think that from
|
||||
experience this is one of the most dense and unapproachable parts of _nanomsg_,
|
||||
in spite of the fact that Martin's goal was precisely the opposite. I
|
||||
consider this a "failed experiment" -- but hey failed experiments are the
|
||||
basis of all great science.
|
||||
|
||||
=== Thread Challenges
|
||||
|
||||
While _nanomsg_ is mostly internally single threaded, I decided to try to
|
||||
emulate the simple architecture of _mangos_ using system threads. (_mangos_
|
||||
benefits greatly from _Go_'s excellent coroutine facility.) Having been well
|
||||
and truly spoiled by _illumos_ threading (and especially _illumos_ kernel
|
||||
threads), I thought this would be a reasonable architecture.
|
||||
|
||||
Sadly, this initial effort, while it worked, scaled incredibly poorly --
|
||||
even so-called "modern" operating systems like _macOS_ 10.12 and _Windows_ 8.1
|
||||
simply melted or failed entirely when creating any non-trivial number of
|
||||
threads. (To me, creating 100 threads should be a no-brainer, especially if
|
||||
one limits the stack size appropriately. I'm used to be able to create
|
||||
thousands of threads without concern. As I said, I've been spoiled.
|
||||
If your system falls over at a mere 200 threads I consider it a toy
|
||||
implementation of threading. Unfortunately most of the mainstream operating
|
||||
systems are therefore toy implementations.)
|
||||
|
||||
Chalk up another failed experiment.
|
||||
|
||||
I did find another approach which is discussed further.
|
||||
|
||||
=== File Descriptor Driven
|
||||
|
||||
Most of the underlying I/O in _nanomsg_ is built around file descriptors,
|
||||
and it's internal usock structure, which is also state machine driven.
|
||||
This means that implementing new transports which might need something
|
||||
other than a file descriptor, is really non-trivial. This stymied my
|
||||
first attempt to add http://www.openssl.org[OpenSSL] support to get TLS
|
||||
added -- _OpenSSL_ has it's own `struct BIO` for this stuff, and I could
|
||||
not see an easy way to convert _nanomsg_'s `usock` stuff to accomodate the
|
||||
`struct BIO`.
|
||||
|
||||
In retrospect, _OpenSSL_ wasn't the ideal choice for an SSL/TLS library,
|
||||
and we have since chosen another (https://tls.mbed.org[mbed TLS]).
|
||||
Still, we needed an abstraction model that was better than just file
|
||||
descriptors for I/O.
|
||||
|
||||
=== Poll
|
||||
|
||||
In order to support use in event driven programming, asynchronous
|
||||
situations, etc. _nanomsg_ offers non-blocking I/O. In order to make
|
||||
this work for end-users, a notification mechanism is required, and
|
||||
nanomsg, in the spirit of following POSIX, offers a notification method
|
||||
based on `poll(2)` or `select(2)`.
|
||||
|
||||
In order for this to work, it offers up a selectable file descriptor
|
||||
for send and another one for receive. When events occur, these are
|
||||
written to, and the user application "clears" these by reading from
|
||||
them. (This is done on behalf of the application by _nanomsg_'s API calls.)
|
||||
|
||||
This means that in addition to the context switch code, there are not
|
||||
fewer than 2 extra system calls executed per message sent or received, and
|
||||
on a mostly idle system as many as 3. This means that to send a message
|
||||
from one process to another you may have to execute up to 6 extra system
|
||||
calls, beyond the 2 required to actually send and receive the message.
|
||||
|
||||
NOTE: Its even more hideous to support this on Windows, where there is no
|
||||
`pipe(2)` system call, so we have to cobble up a loopback TCP connection
|
||||
just for this event notification, in addition to the system call
|
||||
explosion.
|
||||
|
||||
There are cases where this file descriptor logic is easier for existing
|
||||
applications to integrate into event loops (e.g. they already have a thread
|
||||
blocked in `poll()`.)
|
||||
|
||||
But for many cases this is not necessary. A simple callback mechanism
|
||||
would be far better, with the FDs available only as an option for code
|
||||
that needs them. This is the approach that we have taken with _nng_.
|
||||
|
||||
As another consequence of our approach, we do not require file descriptors
|
||||
for sockets at all, so it is possible to create applications containing
|
||||
_many_ thousands of `inproc` sockets with no files open at all. (Obviously
|
||||
if you're going to perform real I/O to other processes or other systems,
|
||||
you're going to need to have the underlying transport file descriptors
|
||||
open, but then the only real limit should be the number of files that you
|
||||
can open on your system. And the number of active connections you can maintain
|
||||
should ideally approach that system limit closely.)
|
||||
|
||||
=== POSIX APIs
|
||||
|
||||
Another of Martin's goals, which seems worthwhile at first, was the
|
||||
attempt to provide a familiar POSIX API (based upon the BSD socket API).
|
||||
As a C programmer coming from UNIX systems, this really attracted me.
|
||||
|
||||
The problem is that the POSIX APIs are actually really horrible. In
|
||||
particular the semantics around `cmsg` are about as arcane and painful as
|
||||
one can imagine. Largely, this has meant that extensions to the `cmsg`
|
||||
API simply have not occurred in _nanomsg_.
|
||||
|
||||
The `cmsg` API specified by POSIX is as bad as it is because POSIX had
|
||||
requirements not to break APIs that already existed, and they needed to
|
||||
shim something that would work with existing implementations, including
|
||||
getting across a system call boundary. _nanomsg_ has never had such
|
||||
constraints.
|
||||
|
||||
Oh, and there was that whole "design by committee" aspect.
|
||||
|
||||
Attempting to retain low numbered "socket descriptors" had its own
|
||||
problems -- a huge source of use-after-close bugs, which made the
|
||||
use of `nn_close()` incredibly dangerous for multithreaded sockets.
|
||||
(If one thread closes and opens a new socket, other threads still using
|
||||
the old socket might wind up accessing the "new" socket without realizing
|
||||
it.)
|
||||
|
||||
The other thing is that BSD socket APIs are super familiar to UNIX C
|
||||
programmers -- but experience with _nanomsg_ has taught us already that these
|
||||
are actually in the minority of _nanomsg_'s users. Most of our users are
|
||||
coming to us from {cpp} (object oriented), _Java_, and _Python_ backgrounds.
|
||||
For them the BSD sockets API is frankly somewhat bizarre and alien.
|
||||
|
||||
With _nng_, we realized that constraining ourselves to the mistakes of the
|
||||
POSIX API was hurting rather than helping. So _nng_ provides a much friendlier
|
||||
interface for getting properties associated with messages.
|
||||
|
||||
In _nng_ we also generally try hard to avoid reusing
|
||||
an identifier until no other option exists. This generally means most
|
||||
applications won't see socket reuse until billions of other sockets
|
||||
have been opened. There is little chance for accidental reuse.
|
||||
|
||||
|
||||
== Compatibility
|
||||
|
||||
Of course, there are a number of existing _nanomsg_ consumers "in the wild"
|
||||
already. It is important to continue to support them. So I decided from
|
||||
the get go to implement a "compatibility" layer, that provides the same
|
||||
API, and as much as possible the same ABI, as legacy _nanomsg_. However,
|
||||
new features and capabilities would not necessarily be exposed to the
|
||||
the legacy API.
|
||||
|
||||
Today _nng_ offers this. You can relink an existing _nanomsg_ binary against
|
||||
_libnng_ instead of _libnn_, and it usually Just Works(TM). Source
|
||||
compatibility is almost as easy, although the application code needs to be
|
||||
modified to use different header files.
|
||||
|
||||
NOTE: I am considering changing the include file in the future so that
|
||||
it matches exactly the _nanomsg_ include path, so that only a compiler
|
||||
flag change would be needed.
|
||||
|
||||
== Asynchronous IO
|
||||
|
||||
As a consequence of our experience with threads being so unscalable,
|
||||
we decided to create a new underlying abstraction modeled largely on
|
||||
Windows IO completion ports. (As bad as so many of the Windows APIs
|
||||
are, the IO completion port stuff is actually pretty nice.) Under the
|
||||
hood in _nng_ all I/O is asynchronous, and we have `nni_aio` objects
|
||||
for each pending I/O. These have an associated completion routine.
|
||||
|
||||
The completion routines are _usually_ run on a separate worker thread
|
||||
(we have many such workers; in theory the number should be tuned to the
|
||||
available number of CPU cores to ensure that we never wait while a CPU
|
||||
core is available for work), but they can be run "synchronously" if
|
||||
the I/O provider knows it is safe to do so (for example the completion
|
||||
is occuring in a context where no locks are held.)
|
||||
|
||||
The `nni_aio` structures are accessible to user applications as well, which can
|
||||
lead to much more efficient and easier to write asynchronous applications,
|
||||
and can aid integration into event-driven systems and runtimes, without
|
||||
requiring extra system calls required by the legacy _nanomsg_ approach.
|
||||
|
||||
There is still performance tuning work to do, especially optimization for
|
||||
specific pollers like `epoll()` and `kqueue()` to address the C10K problem,
|
||||
but that work is already in progress.
|
||||
|
||||
== Portability & Embeddability
|
||||
|
||||
A significant goal of _nng_ is to be portable to many kinds of different
|
||||
kinds of systems, and embedded in systems that do not support POSIX or Win32
|
||||
APIs. To that end we have a clear platform portability layer. We do require
|
||||
that platforms supply entry points for certain networking, synchronization,
|
||||
threading, and timekeeping functions, but these are fairly straight-forward
|
||||
to implement on any reasonable 32-bit or 64-bit system, including most
|
||||
embedded operating systems.
|
||||
|
||||
Additionally, this portability layer may be used to build other kinds of
|
||||
experiments -- for example it should be relatively straight-forward to provide
|
||||
a "platform" based on one of the various coroutine libraries such as Martin's
|
||||
http://libdill.org[libdill] or https://swtch.com/libtask/[libtask].
|
||||
|
||||
TIP: If you want to write a coroutine-based platform, let me know!
|
||||
|
||||
== New Transports
|
||||
|
||||
The other, most critical, motivation behind _nng_ was to enable an easier
|
||||
creation of new transports. In particular, one client (
|
||||
http://www.capitar.com[Capitar IT Group BV])
|
||||
contracted the creation of a http://www.zerotier.com[ZeroTier] transport for
|
||||
_nanomsg_.
|
||||
|
||||
After beating my head against the state machines some more, I finally asked
|
||||
myself if it would not be easier just to rewrite _nanomsg_ using the model
|
||||
I had created for _mangos_.
|
||||
|
||||
In retrospect, I'm not sure that the answer was a clear and definite yes
|
||||
in favor of _nng_, but for the other things I want to do, it has enabled a
|
||||
lot of new work. The ZeroTier transport was created with a relatively
|
||||
modest amount of effort, in spite of being based upon a connectionless
|
||||
transport. I do not believe I could have done this easily in the existing
|
||||
_nanomsg_.
|
||||
|
||||
I've since added a rich TLS transport, and have implemented a WebSocket
|
||||
transport that is far more capable than that in _nanomsg_, as it can
|
||||
support TLS and sharing the TCP port across multiple _nng_ sockets (using
|
||||
the path to discriminate) or even other HTTP services.
|
||||
|
||||
There are already plans afoot for other kinds of transports using QUIC
|
||||
or KCP or SSH, as well as a pure UDP transport. The new _nng_ transport
|
||||
layer makes implementation of these all fairly straight-forward.
|
||||
|
||||
== HTTP and Other services
|
||||
|
||||
As part of implementing a real WebSocket transport, it was necessary to
|
||||
implement at least some HTTP capabilities. Rather than just settle for a toy
|
||||
implementation, _nng_ has a very capable HTTP server and client framework.
|
||||
The server can be used to build real web services, so it becomes possible
|
||||
for example to serve static content, REST API, and _nng_ based services
|
||||
all from the same TCP port using the same program.
|
||||
|
||||
We've also made the WebSocket services fairly generic, which may support
|
||||
a plethora of other kinds of transports and services.
|
||||
|
||||
There is also a portability layer -- so some common services (threading,
|
||||
timing, etc.) are provided in the _nng_ library to help make writing
|
||||
portable _nng_ applications easier.
|
||||
|
||||
It will not surprise me if developers start finding uses for _nng_ that
|
||||
have nothing to do with Scalability Protocols.
|
||||
|
||||
== Separate Contexts
|
||||
|
||||
As part of working on a demo suite of applications, I realized that the
|
||||
requirement to use raw mode sockets for concurrent applications was rather
|
||||
onerous, forcing application developers to re-implement much of the
|
||||
same logic that is already in _nng_.
|
||||
|
||||
Thus was the born the idea of separating the context for protocols from
|
||||
the socket, allowing multiple contexts (each of which managing it's own
|
||||
REQ/REP state machinery) to be allocated and used on a single socket.
|
||||
|
||||
This was a large change indeed, but we believe application developers
|
||||
are going to find it *much* easier to write scalable applications,
|
||||
and hopefully the uses of raw mode and applications needing to inspect
|
||||
or generate their own application headers will vanish.
|
||||
|
||||
Note that these contexts are entirely optional -- an application can
|
||||
still use the implicit context associated with the socket just like
|
||||
always, if it has no need for extra concurrency.
|
||||
|
||||
One side benefit of this work was that we identified several places
|
||||
to make _nng_ perform more efficiently, reducing the number of context
|
||||
switches and extra raw vs. cooked logic.
|
||||
|
||||
== Towards _nanomsg_ 2.0
|
||||
|
||||
It is my intention that _nng_ ultimately replace _nanomsg_. I do think of it
|
||||
as "nanomsg 2.0". In fact "nng" stands for "nanomsg next generation" in
|
||||
my mind. Some day soon I'm hoping that the various website
|
||||
references to nanomsg my simply be updated to point at _nng_. It is not
|
||||
clear to me whether at that time I will simply rename the existing
|
||||
code to _nanomsg_, nanomsg2, or leave it as _nng_.
|
11
external/nng/docs/README.txt
vendored
Normal file
11
external/nng/docs/README.txt
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
This contains the nng documentation for API users.
|
||||
|
||||
The documentation is written in asciidoc in the form of man pages. It is
|
||||
automatically formatted for display on the website.
|
||||
|
||||
It is possible to emit TROFF sources for use by the UNIX man page, and HTML
|
||||
for online viewing. asciidoctor supports PDF and EPUB formats via plugins,
|
||||
so there are still more options available.
|
||||
|
||||
The man pages are in the "man" directory. The reason those are separate
|
||||
is that they get special treatment. Other documentation is located here.
|
437
external/nng/docs/man/CMakeLists.txt
vendored
Normal file
437
external/nng/docs/man/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,437 @@
|
|||
#
|
||||
# Copyright 2020 Staysail Systems, Inc. <info@staysail.tech>
|
||||
# Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||||
# Copyright 2019 Devolutions <info@devolutions.net>
|
||||
#
|
||||
# This software 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.
|
||||
|
||||
# We default to off here.
|
||||
option(NNG_ENABLE_DOC "Enable building documentation." OFF)
|
||||
|
||||
if (NNG_ENABLE_DOC)
|
||||
find_program(ASCIIDOCTOR asciidoctor)
|
||||
if (NOT ASCIIDOCTOR)
|
||||
message(WARNING "Could not find asciidoctor: skipping docs")
|
||||
set(NNG_ENABLE_DOC OFF)
|
||||
else ()
|
||||
message(STATUS "Using asciidoctor at ${ASCIIDOCTOR}")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (NNG_ENABLE_DOC)
|
||||
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)
|
||||
|
||||
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}.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)
|
||||
|
||||
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)
|
||||
|
||||
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_bool
|
||||
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
|
||||
)
|
||||
|
||||
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
|
||||
)
|
||||
|
||||
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_thread_set_name
|
||||
)
|
||||
|
||||
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
|
||||
)
|
||||
|
||||
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_engine_description
|
||||
nng_tls_engine_fips_mode
|
||||
nng_tls_engine_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_abstract
|
||||
nng_sockaddr_in
|
||||
nng_sockaddr_in6
|
||||
nng_sockaddr_inproc
|
||||
nng_sockaddr_ipc
|
||||
nng_sockaddr_zt
|
||||
nng_socket
|
||||
nng_stat
|
||||
nng_url
|
||||
|
||||
nng_stream
|
||||
nng_stream_dialer
|
||||
nng_stream_listener
|
||||
|
||||
nng_tcp_options
|
||||
nng_ipc_options
|
||||
nng_tls_config
|
||||
nng_tls_engine
|
||||
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
|
||||
)
|
||||
|
||||
foreach (F ${NNG_MAN1})
|
||||
nng_man(${F} 1)
|
||||
endforeach ()
|
||||
|
||||
foreach (F ${NNG_MAN3})
|
||||
nng_man(${F} 3)
|
||||
endforeach ()
|
||||
|
||||
foreach (F ${NNG_MAN3COMPAT})
|
||||
nng_man(${F} 3compat)
|
||||
endforeach ()
|
||||
|
||||
foreach (F ${NNG_MAN3HTTP})
|
||||
nng_man(${F} 3http)
|
||||
endforeach ()
|
||||
|
||||
foreach (F ${NNG_MAN3STR})
|
||||
nng_man(${F} 3str)
|
||||
endforeach ()
|
||||
|
||||
foreach (F ${NNG_MAN3SUPP})
|
||||
nng_man(${F} 3supp)
|
||||
endforeach ()
|
||||
|
||||
foreach (F ${NNG_MAN3TLS})
|
||||
nng_man(${F} 3tls)
|
||||
endforeach ()
|
||||
|
||||
foreach (F ${NNG_MAN5})
|
||||
nng_man(${F} 5)
|
||||
endforeach ()
|
||||
|
||||
foreach (F ${NNG_MAN7})
|
||||
nng_man(${F} 7)
|
||||
endforeach ()
|
||||
|
||||
add_custom_target(man ALL DEPENDS ${NNG_MANS})
|
||||
add_custom_target(html ALL DEPENDS ${NNG_HTMLS})
|
||||
endif ()
|
460
external/nng/docs/man/libnng.3.adoc
vendored
Normal file
460
external/nng/docs/man/libnng.3.adoc
vendored
Normal file
|
@ -0,0 +1,460 @@
|
|||
= libnng(3)
|
||||
//
|
||||
// Copyright 2020 Staysail Systems, Inc. <info@staysail.tech>
|
||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||||
// Copyright 2019 Devolutions <info@devolutions.net>
|
||||
// Copyright 2020 Dirac Research <robert.bielik@dirac.com>
|
||||
//
|
||||
// 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
|
||||
|
||||
libnng - nanomsg next generation library
|
||||
|
||||
== SYNOPSIS
|
||||
|
||||
*cc* [_flags_] _files_ *-lnng* [_libraries_]
|
||||
|
||||
== DESCRIPTION
|
||||
|
||||
xref:nng.7.adoc[_NNG_] provides a common messaging framework
|
||||
intended to solve common communication problems in distributed applications.
|
||||
|
||||
It provides a C language API.
|
||||
|
||||
=== Common Functions
|
||||
|
||||
The following common functions exist in _libnng_.
|
||||
|
||||
|===
|
||||
|xref:nng_alloc.3.adoc[nng_alloc()]|allocate memory
|
||||
|xref:nng_free.3.adoc[nng_free()]|free memory
|
||||
|xref:nng_strdup.3.adoc[nng_strdup()]|duplicate string
|
||||
|xref:nng_strerror.3.adoc[nng_strerror()]|return an error description
|
||||
|xref:nng_strfree.3.adoc[nng_strfree()]|free string
|
||||
|xref:nng_version.3.adoc[nng_version()]|report library version
|
||||
|===
|
||||
|
||||
=== Socket Functions
|
||||
|
||||
The following functions operate on sockets.
|
||||
|
||||
|===
|
||||
|xref:nng_close.3.adoc[nng_close()]|close socket
|
||||
|xref:nng_dial.3.adoc[nng_dial()]|create and start dialer
|
||||
|xref:nng_getopt.3.adoc[nng_getopt()]|get socket option
|
||||
|xref:nng_listen.3.adoc[nng_listen()]|create and start listener
|
||||
|xref:nng_recv.3.adoc[nng_recv()]|receive data
|
||||
|xref:nng_send.3.adoc[nng_send()]|send data
|
||||
|xref:nng_setopt.3.adoc[nng_setopt()]|set socket option
|
||||
|xref:nng_socket_get.3.adoc[nng_socket_get()]|get socket option
|
||||
|xref:nng_socket_id.3.adoc[nng_socket_id()]|get numeric socket identifier
|
||||
|xref:nng_socket_set.3.adoc[nng_socket_set()]|set socket option
|
||||
|===
|
||||
|
||||
=== Connection Management
|
||||
|
||||
The following functions are used with either listeners, or dialers.
|
||||
Listeners accept incoming connection requests, and dialers make them.
|
||||
|
||||
|===
|
||||
|xref:nng_dial.3.adoc[nng_dial()]|create and start dialer
|
||||
|xref:nng_dialer_close.3.adoc[nng_dialer_close()]|close dialer
|
||||
|xref:nng_dialer_create.3.adoc[nng_dialer_create()]|create dialer
|
||||
|xref:nng_dialer_get.3.adoc[nng_dialer_get()]|get dialer option
|
||||
|xref:nng_dialer_getopt.3.adoc[nng_dialer_getopt()]|get dialer option
|
||||
|xref:nng_dialer_id.3.adoc[nng_dialer_id()]|get numeric dialer identifier
|
||||
|xref:nng_dialer_set.3.adoc[nng_dialer_set()]|set dialer option
|
||||
|xref:nng_dialer_setopt.3.adoc[nng_dialer_setopt()]|set dialer option
|
||||
|xref:nng_dialer_start.3.adoc[nng_dialer_start()]|start dialer
|
||||
|xref:nng_listen.3.adoc[nng_listen()]|create and start listener
|
||||
|xref:nng_listener_close.3.adoc[nng_listener_close()]|close listener
|
||||
|xref:nng_listener_create.3.adoc[nng_listener_create()]|create listener
|
||||
|xref:nng_listener_get.3.adoc[nng_listener_get()]|get listener option
|
||||
|xref:nng_listener_getopt.3.adoc[nng_listener_getopt()]|get listener option
|
||||
|xref:nng_listener_id.3.adoc[nng_listener_id()]|get numeric listener identifier
|
||||
|xref:nng_listener_set.3.adoc[nng_listener_set()]|set listener option
|
||||
|xref:nng_listener_setopt.3.adoc[nng_listener_setopt()]|set listener option
|
||||
|xref:nng_listener_start.3.adoc[nng_listener_start()]|start listener
|
||||
|xref:nng_pipe_close.3.adoc[nng_pipe_close()]|close pipe
|
||||
|xref:nng_pipe_dialer.3.adoc[nng_pipe_dialer()]|return dialer that created pipe
|
||||
|xref:nng_pipe_get.3.adoc[nng_pipe_get()]|get pipe option
|
||||
|xref:nng_pipe_getopt.3.adoc[nng_pipe_getopt()]|get pipe option
|
||||
|xref:nng_pipe_id.3.adoc[nng_pipe_id()]|get numeric pipe identifier
|
||||
|xref:nng_pipe_listener.3.adoc[nng_pipe_listener()]|return listener that created pipe
|
||||
|xref:nng_pipe_notify.3.adoc[nng_pipe_notify()]|register pipe notification callback
|
||||
|xref:nng_pipe_socket.3.adoc[nng_pipe_socket()]|return owning socket for pipe
|
||||
|===
|
||||
|
||||
=== Message Handling Functions
|
||||
|
||||
Applications desiring to use the richest part of _libnng_ will want to
|
||||
use the message API, where a message structure is passed between functions.
|
||||
This API provides the most power support for zero-copy.
|
||||
|
||||
Messages are divided into a header and body, where the body generally carries
|
||||
user-payload and the header carries protocol specific header information.
|
||||
Most applications will only interact with the body.
|
||||
|
||||
|===
|
||||
|xref:nng_msg_alloc.3.adoc[nng_msg_alloc()]|allocate a message
|
||||
|xref:nng_msg_append.3.adoc[nng_msg_append()]|append to message body
|
||||
|xref:nng_msg_body.3.adoc[nng_msg_body()]|return message body
|
||||
|xref:nng_msg_capacity.3.adoc[nng_msg_capacity()]|return capacity allocated for message body
|
||||
|xref:nng_msg_chop.3.adoc[nng_msg_chop()]|remove data from end of message body
|
||||
|xref:nng_msg_clear.3.adoc[nng_msg_clear()]|clear message body
|
||||
|xref:nng_msg_dup.3.adoc[nng_msg_dup()]|duplicate a message
|
||||
|xref:nng_msg_free.3.adoc[nng_msg_free()]|free a message
|
||||
|xref:nng_msg_get_pipe.3.adoc[nng_msg_get_pipe()]|get pipe for message
|
||||
|xref:nng_msg_insert.3.adoc[nng_msg_insert()]|prepend to message body
|
||||
|xref:nng_msg_len.3.adoc[nng_msg_len()]|return the message body length
|
||||
|xref:nng_msg_realloc.3.adoc[nng_msg_realloc()]|reallocate a message
|
||||
|xref:nng_msg_reserve.3.adoc[nng_msg_reserve()]|reserve storage for message body
|
||||
|xref:nng_msg_set_pipe.3.adoc[nng_msg_set_pipe()]|set pipe for message
|
||||
|xref:nng_msg_trim.3.adoc[nng_msg_trim()]|remove data from start of message body
|
||||
|xref:nng_recvmsg.3.adoc[nng_recvmsg()]|receive a message
|
||||
|xref:nng_sendmsg.3.adoc[nng_sendmsg()]|send a message
|
||||
|===
|
||||
|
||||
==== Message Header Handling
|
||||
|
||||
TIP: Few applications will need these functions, as message headers are only
|
||||
used to carry protocol-specific content. However, applications which use raw
|
||||
mode may need to access the header of messages.
|
||||
|
||||
|===
|
||||
|xref:nng_msg_header.3.adoc[nng_msg_header()]|return message header
|
||||
|xref:nng_msg_header_append.3.adoc[nng_msg_header_append()]|append to message header
|
||||
|xref:nng_msg_header_chop.3.adoc[nng_msg_header_chop()]|remove data from end of message header
|
||||
|xref:nng_msg_header_clear.3.adoc[nng_msg_header_clear()]|clear message header
|
||||
|xref:nng_msg_header_insert.3.adoc[nng_msg_header_insert()]|prepend to message header
|
||||
|xref:nng_msg_header_len.3.adoc[nng_msg_header_len()]|return the message header length
|
||||
|xref:nng_msg_header_trim.3.adoc[nng_msg_header_trim()]|remove data from start of message header
|
||||
|===
|
||||
|
||||
=== Asynchronous Operations
|
||||
|
||||
Most applications will interact with _NNG_ synchronously; that is that
|
||||
functions such as xref:nng_send.3.adoc[`nng_send()`] will block the calling
|
||||
thread until the operation has completed.
|
||||
|
||||
NOTE: Synchronous operations which send messages may return before the
|
||||
message has actually been received, or even transmitted. Instead, These
|
||||
functions return as soon as the message was successfully queued for
|
||||
delivery.
|
||||
|
||||
Asynchronous operations behave differently. These operations are
|
||||
initiated by the calling thread, but control returns immediately to
|
||||
the calling thread. When the operation is subsequently completed (regardless
|
||||
of whether this was successful or not), then a user supplied function
|
||||
is executed.
|
||||
|
||||
A context structure, an xref:nng_aio.5.adoc[`nng_aio`], is allocated and
|
||||
associated with each asynchronous operation.
|
||||
Only a single asynchronous operation may be associated with an
|
||||
`nng_aio` at any time.
|
||||
|
||||
The following functions are used in the asynchronous model:
|
||||
|
||||
|===
|
||||
|xref:nng_aio_abort.3.adoc[nng_aio_abort()]|abort asynchronous I/O operation
|
||||
|xref:nng_aio_alloc.3.adoc[nng_aio_alloc()]|allocate asynchronous I/O handle
|
||||
|xref:nng_aio_begin.3.adoc[nng_aio_begin()]|begin asynchronous I/O operation
|
||||
|xref:nng_aio_cancel.3.adoc[nng_aio_cancel()]|cancel asynchronous I/O operation
|
||||
|xref:nng_aio_count.3.adoc[nng_aio_count()]|return number of bytes transferred
|
||||
|xref:nng_aio_defer.3.adoc[nng_aio_defer()]|defer asynchronous I/O operation
|
||||
|xref:nng_aio_finish.3.adoc[nng_aio_finish()]|finish asynchronous I/O operation
|
||||
|xref:nng_aio_free.3.adoc[nng_aio_free()]|free asynchronous I/O handle
|
||||
|xref:nng_aio_get_input.3.adoc[nng_aio_get_input()]|return input parameter
|
||||
|xref:nng_aio_get_msg.3.adoc[nng_aio_get_msg()]|get message from an asynchronous receive
|
||||
|xref:nng_aio_get_output.3.adoc[nng_aio_get_output()]|return output result
|
||||
|xref:nng_aio_free.3.adoc[nng_aio_reap()]|reap asynchronous I/O handle
|
||||
|xref:nng_aio_result.3.adoc[nng_aio_result()]|return result of asynchronous operation
|
||||
|xref:nng_aio_set_input.3.adoc[nng_aio_set_input()]|set input parameter
|
||||
|xref:nng_aio_set_iov.3.adoc[nng_aio_set_iov()]|set scatter/gather vector
|
||||
|xref:nng_aio_set_msg.3.adoc[nng_aio_set_msg()]|set message for an asynchronous send
|
||||
|xref:nng_aio_set_output.3.adoc[nng_aio_set_output()]|set output result
|
||||
|xref:nng_aio_set_timeout.3.adoc[nng_aio_set_timeout()]|set asynchronous I/O timeout
|
||||
|xref:nng_aio_stop.3.adoc[nng_aio_stop()]|stop asynchronous I/O operation
|
||||
|xref:nng_aio_wait.3.adoc[nng_aio_wait()]|wait for asynchronous I/O operation
|
||||
|xref:nng_recv_aio.3.adoc[nng_recv_aio()]|receive message asynchronously
|
||||
|xref:nng_send_aio.3.adoc[nng_send_aio()]|send message asynchronously
|
||||
|xref:nng_sleep_aio.3.adoc[nng_sleep_aio()]|sleep asynchronously
|
||||
|===
|
||||
|
||||
=== Protocols
|
||||
|
||||
The following functions are used to construct a socket with a specific protocol:
|
||||
|
||||
|===
|
||||
|xref:nng_bus_open.3.adoc[nng_bus_open()]|open a bus socket
|
||||
|xref:nng_pair_open.3.adoc[nng_pair_open()]|open a pair socket
|
||||
|xref:nng_pub_open.3.adoc[nng_pub_open()]|open a pub socket
|
||||
|xref:nng_pull_open.3.adoc[nng_pull_open()]|open a pull socket
|
||||
|xref:nng_push_open.3.adoc[nng_push_open()]|open a push socket
|
||||
|xref:nng_rep_open.3.adoc[nng_rep_open()]|open a rep socket
|
||||
|xref:nng_req_open.3.adoc[nng_req_open()]|open a req socket
|
||||
|xref:nng_respondent_open.3.adoc[nng_respondent_open()]|open a respondent socket
|
||||
|xref:nng_sub_open.3.adoc[nng_sub_open()]|open a sub socket
|
||||
|xref:nng_surveyor_open.3.adoc[nng_surveyor_open()]|open a surveyor socket
|
||||
|===
|
||||
|
||||
=== Transports
|
||||
|
||||
The following functions are used to register a transport for use.
|
||||
|
||||
|===
|
||||
| xref:nng_inproc_register.3.adoc[nng_inproc_register()]|register inproc transport
|
||||
| xref:nng_ipc_register.3.adoc[nng_ipc_register()]|register IPC transport
|
||||
| xref:nng_tcp_register.3.adoc[nng_tcp_register()]|register TCP transport
|
||||
| xref:nng_tls_register.3.adoc[nng_tls_register()]|register TLS transport
|
||||
| xref:nng_ws_register.3.adoc[nng_ws_register()]|register WebSocket transport
|
||||
| xref:nng_wss_register.3.adoc[nng_wss_register()]|register WebSocket Secure transport
|
||||
| xref:nng_zt_register.3.adoc[nng_zt_register()]|register ZeroTier transport
|
||||
|===
|
||||
|
||||
=== Protocol Contexts
|
||||
|
||||
The following functions are useful to separate the protocol processing
|
||||
from a socket object, into a separate context.
|
||||
This can allow multiple contexts to be created on a single socket for
|
||||
concurrent applications.
|
||||
|
||||
|===
|
||||
|xref:nng_ctx_close.3.adoc[nng_ctx_close()]|close context
|
||||
|xref:nng_ctx_get.3.adoc[nng_ctx_get()]|get context option
|
||||
|xref:nng_ctx_getopt.3.adoc[nng_ctx_getopt()]|get context option
|
||||
|xref:nng_ctx_id.3.adoc[nng_ctx_id()]|get numeric context identifier
|
||||
|xref:nng_ctx_open.3.adoc[nng_ctx_open()]|create context
|
||||
|xref:nng_ctx_recv.3.adoc[nng_ctx_recv()]|receive message using context asynchronously
|
||||
|xref:nng_ctx_send.3.adoc[nng_ctx_send()]|send message using context asynchronously
|
||||
|xref:nng_ctx_set.3.adoc[nng_ctx_set()]|set context option
|
||||
|xref:nng_ctx_setopt.3.adoc[nng_ctx_setopt()]|set context option
|
||||
|===
|
||||
|
||||
=== Statistics
|
||||
|
||||
The following functions provide access to statistics which can be used
|
||||
to observe program behaviors and as an aid in troubleshooting.
|
||||
|
||||
|===
|
||||
|xref:nng_stat_bool.3.adoc[nng_stat_bool()]|get statistic Boolean value
|
||||
|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
|
||||
|xref:nng_stat_timestamp.3.adoc[nng_stat_timestamp()]|get statistic timestamp
|
||||
|xref:nng_stat_type.3.adoc[nng_stat_type()]|get statistic type
|
||||
|xref:nng_stat_unit.3.adoc[nng_stat_unit()]|get statistic unit
|
||||
|xref:nng_stat_value.3.adoc[nng_stat_value()]|get statistic numeric value
|
||||
|xref:nng_stats_free.3.adoc[nng_stats_free()]|free statistics
|
||||
|xref:nng_stats_get.3.adoc[nng_stats_get()]|get statistics
|
||||
|===
|
||||
|
||||
=== URL Object
|
||||
|
||||
Common functionality is supplied for parsing and handling
|
||||
universal resource locators (URLS).
|
||||
|
||||
|===
|
||||
|xref:nng_url_clone.3.adoc[nng_url_clone()]|clone URL structure
|
||||
|xref:nng_url_free.3.adoc[nng_url_free()]|free URL structure
|
||||
|xref:nng_url_parse.3.adoc[nng_url_parse()]|create URL structure from string
|
||||
|===
|
||||
|
||||
|
||||
=== Supplemental API
|
||||
|
||||
These supplemental functions are not intrinsic to building
|
||||
network applications with _NNG_, but they are made available
|
||||
as a convenience to aid in creating portable applications.
|
||||
|
||||
|===
|
||||
|xref:nng_clock.3supp.adoc[nng_clock()]|get time
|
||||
|xref:nng_cv_alloc.3supp.adoc[nng_cv_alloc()]|allocate condition variable
|
||||
|xref:nng_cv_free.3supp.adoc[nng_cv_free()]|free condition variable
|
||||
|xref:nng_cv_until.3supp.adoc[nng_cv_until()]|wait for condition or timeout
|
||||
|xref:nng_cv_wait.3supp.adoc[nng_cv_wait()]|wait for condition
|
||||
|xref:nng_cv_wake.3supp.adoc[nng_cv_wake()]|wake all waiters
|
||||
|xref:nng_cv_wake1.3supp.adoc[nng_cv_wake1()]|wake one waiter
|
||||
|xref:nng_msleep.3supp.adoc[nng_msleep()]|sleep for milliseconds
|
||||
|xref:nng_mtx_alloc.3supp.adoc[nng_mtx_alloc()]|allocate mutex
|
||||
|xref:nng_mtx_free.3supp.adoc[nng_mtx_free()]|free mutex
|
||||
|xref:nng_mtx_lock.3supp.adoc[nng_mtx_lock()]|lock mutex
|
||||
|xref:nng_mtx_unlock.3supp.adoc[nng_mtx_unlock()]|unlock mutex
|
||||
|xref:nng_opts_parse.3supp.adoc[nng_opts_parse()]|parse command line options
|
||||
|xref:nng_random.3supp.adoc[nng_random()]|get random number
|
||||
|xref:nng_thread_create.3supp.adoc[nng_thread_create()]|create thread
|
||||
|xref:nng_thread_destroy.3supp.adoc[nng_thread_destroy()]|reap thread
|
||||
|xref:nng_thread_set_name.3supp.adoc[nng_thread_set_name()]|set thread name
|
||||
|===
|
||||
|
||||
=== Byte Streams
|
||||
|
||||
These functions are available for use with byte streams.
|
||||
They are considered low-level, for uses where the higher level functions
|
||||
using Scalability Protocols are inappropriate.
|
||||
|
||||
Byte streams, represented by
|
||||
xref:nng_stream.5.adoc[`nng_stream`] objects, correspond to underlying
|
||||
connections such as TCP connections or named pipes.
|
||||
They are created by either
|
||||
xref:nng_stream_dialer.5.adoc[`nng_stream_dialer`] or
|
||||
xref:nng_stream_listener.5.adoc[`nng_stream_listener`] objects.
|
||||
|
||||
|===
|
||||
|xref:nng_stream_close.3str.adoc[nng_stream_close()]|close byte stream
|
||||
|xref:nng_stream_dialer_alloc.3str.adoc[nng_stream_dialer_alloc()]|allocate byte stream dialer
|
||||
|xref:nng_stream_dialer_close.3str.adoc[nng_stream_dialer_close()]|close byte stream dialer
|
||||
|xref:nng_stream_dialer_dial.3str.adoc[nng_stream_dialer_dial()]|initiate outgoing byte stream
|
||||
|xref:nng_stream_dialer_free.3str.adoc[nng_stream_dialer_free()]|free byte stream dialer
|
||||
|xref:nng_stream_dialer_get.3str.adoc[nng_stream_dialer_get()]|get option from byte stream dialer
|
||||
|xref:nng_stream_dialer_set.3str.adoc[nng_stream_dialer_set()]|set option on byte stream dialer
|
||||
|xref:nng_stream_free.3str.adoc[nng_stream_free()]|free byte stream
|
||||
|xref:nng_stream_get.3str.adoc[nng_stream_get()]|get option from byte stream
|
||||
|xref:nng_stream_listener_accept.3str.adoc[nng_stream_listener_accept()]|accept incoming byte stream
|
||||
|xref:nng_stream_listener_alloc.3str.adoc[nng_stream_listener_alloc()]|allocate byte stream listener
|
||||
|xref:nng_stream_listener_close.3str.adoc[nng_stream_listener_close()]|close byte stream listener
|
||||
|xref:nng_stream_listener_free.3str.adoc[nng_stream_listener_free()]|free byte stream listener
|
||||
|xref:nng_stream_listener_get.3str.adoc[nng_stream_listener_get()]|get option from byte stream listener
|
||||
|xref:nng_stream_listener_listen.3str.adoc[nng_stream_listener_listen()]|bind byte stream listener to address
|
||||
|xref:nng_stream_listener_set.3str.adoc[nng_stream_listener_set()]|set option on byte stream listener
|
||||
|xref:nng_stream_recv.3str.adoc[nng_stream_recv()]|receive from byte stream
|
||||
|xref:nng_stream_send.3str.adoc[nng_stream_send()]|send to byte stream
|
||||
|xref:nng_stream_set.3str.adoc[nng_stream_set()]|set option on byte stream
|
||||
|===
|
||||
|
||||
=== HTTP Support
|
||||
|
||||
The library may be configured with support for HTTP, and this will
|
||||
be the case if WebSocket support is configured as well.
|
||||
In this case, it is possible to access functionality to support the creation of
|
||||
HTTP (and HTTP/S if TLS support is present) servers and clients.
|
||||
|
||||
==== Common HTTP Functions
|
||||
|
||||
The following functions are used to work with HTTP requests, responses,
|
||||
and connections.
|
||||
|
||||
|===
|
||||
|xref:nng_http_conn_close.3http.adoc[nng_http_conn_close()]|close HTTP connection
|
||||
|xref:nng_http_conn_read.3http.adoc[nng_http_conn_read()]|read from HTTP connection
|
||||
|xref:nng_http_conn_read_all.3http.adoc[nng_http_conn_read_all()]|read all from HTTP connection
|
||||
|xref:nng_http_conn_read_req.3http.adoc[nng_http_conn_read_req()]|read HTTP request
|
||||
|xref:nng_http_conn_read_res.3http.adoc[nng_http_conn_read_res()]|read HTTP response
|
||||
|xref:nng_http_conn_write.3http.adoc[nng_http_conn_write()]|write to HTTP connection
|
||||
|xref:nng_http_conn_write_all.3http.adoc[nng_http_conn_write_all()]|write all to HTTP connection
|
||||
|xref:nng_http_conn_write_req.3http.adoc[nng_http_conn_write_req()]|write HTTP request
|
||||
|xref:nng_http_conn_write_res.3http.adoc[nng_http_conn_write_res()]|write HTTP response
|
||||
|xref:nng_http_req_add_header.3http.adoc[nng_http_req_add_header()]|add HTTP request header
|
||||
|xref:nng_http_req_alloc.3http.adoc[nng_http_req_alloc()]|allocate HTTP request structure
|
||||
|xref:nng_http_req_copy_data.3http.adoc[nng_http_req_copy_data()]|copy HTTP request body
|
||||
|xref:nng_http_req_del_header.3http.adoc[nng_http_req_del_header()]|delete HTTP request header
|
||||
|xref:nng_http_req_free.3http.adoc[nng_http_req_free()]|free HTTP request structure
|
||||
|xref:nng_http_req_get_data.3http.adoc[nng_http_req_get_data()]|get HTTP request body
|
||||
|xref:nng_http_req_get_header.3http.adoc[nng_http_req_get_header()]|return HTTP request header
|
||||
|xref:nng_http_req_get_method.3http.adoc[nng_http_req_get_method()]|return HTTP request method
|
||||
|xref:nng_http_req_get_uri.3http.adoc[nng_http_req_get_uri()]|return HTTP request URI
|
||||
|xref:nng_http_req_get_version.3http.adoc[nng_http_req_get_version()]|return HTTP request protocol version
|
||||
|xref:nng_http_req_reset.3http.adoc[nng_http_req_reset()]|reset HTTP request structure
|
||||
|xref:nng_http_req_set_data.3http.adoc[nng_http_req_set_data()]|set HTTP request body
|
||||
|xref:nng_http_req_set_header.3http.adoc[nng_http_req_set_header()]|set HTTP request header
|
||||
|xref:nng_http_req_set_method.3http.adoc[nng_http_req_set_method()]|set HTTP request method
|
||||
|xref:nng_http_req_set_uri.3http.adoc[nng_http_req_set_uri()]|set HTTP request URI
|
||||
|xref:nng_http_req_set_version.3http.adoc[nng_http_req_set_version()]|set HTTP request protocol version
|
||||
|xref:nng_http_res_add_header.3http.adoc[nng_http_res_add_header()]|add HTTP response header
|
||||
|xref:nng_http_res_alloc.3http.adoc[nng_http_res_alloc()]|allocate HTTP response structure
|
||||
|xref:nng_http_res_alloc_error.3http.adoc[nng_http_res_alloc_error()]|allocate HTTP error response
|
||||
|xref:nng_http_res_copy_data.3http.adoc[nng_http_res_copy_data()]|copy HTTP response body
|
||||
|xref:nng_http_res_del_header.3http.adoc[nng_http_res_del_header()]|delete HTTP response header
|
||||
|xref:nng_http_res_free.3http.adoc[nng_http_res_free()]|free HTTP response structure
|
||||
|xref:nng_http_res_get_data.3http.adoc[nng_http_res_get_data()]|get HTTP response body
|
||||
|xref:nng_http_res_get_header.3http.adoc[nng_http_res_get_header()]|return HTTP response header
|
||||
|xref:nng_http_res_get_reason.3http.adoc[nng_http_res_get_reason()]|return HTTP response reason
|
||||
|xref:nng_http_res_get_status.3http.adoc[nng_http_res_get_status()]|return HTTP response status
|
||||
|xref:nng_http_res_get_version.3http.adoc[nng_http_res_get_version()]|return HTTP response protocol version
|
||||
|xref:nng_http_res_reset.3http.adoc[nng_http_res_reset()]|reset HTTP response structure
|
||||
|xref:nng_http_res_set_data.3http.adoc[nng_http_res_set_data()]|set HTTP response body
|
||||
|xref:nng_http_res_set_header.3http.adoc[nng_http_res_set_header()]|set HTTP response header
|
||||
|xref:nng_http_res_set_reason.3http.adoc[nng_http_res_set_reason()]|set HTTP response reason
|
||||
|xref:nng_http_res_set_status.3http.adoc[nng_http_res_set_status()]|set HTTP response status
|
||||
|xref:nng_http_res_set_version.3http.adoc[nng_http_res_set_version()]|set HTTP response protocol version
|
||||
|===
|
||||
|
||||
==== HTTP Client Functions
|
||||
|
||||
These functions are intended for use with HTTP client applications.
|
||||
|
||||
|===
|
||||
|xref:nng_http_client_alloc.3http.adoc[nng_http_client_alloc()]|allocate HTTP client
|
||||
|xref:nng_http_client_connect.3http.adoc[nng_http_client_connect()]|establish HTTP client connection
|
||||
|xref:nng_http_client_free.3http.adoc[nng_http_client_free()]|free HTTP client
|
||||
|xref:nng_http_client_get_tls.3http.adoc[nng_http_client_get_tls()]|get HTTP client TLS configuration
|
||||
|xref:nng_http_client_set_tls.3http.adoc[nng_http_client_set_tls()]|set HTTP client TLS configuration
|
||||
|xref:nng_http_client_transact.3http.adoc[nng_http_client_transact()]|perform one HTTP transaction
|
||||
|xref:nng_http_conn_transact.3http.adoc[nng_http_conn_transact()]|perform one HTTP transaction on connection
|
||||
|===
|
||||
|
||||
==== HTTP Server Functions
|
||||
|
||||
These functions are intended for use with HTTP server applications.
|
||||
|
||||
|===
|
||||
|xref:nng_http_handler_alloc.3http.adoc[nng_http_handler_alloc()]|allocate HTTP server handler
|
||||
|xref:nng_http_handler_collect_body.3http.adoc[nng_http_handler_collect_body()]|set HTTP handler to collect request body
|
||||
|xref:nng_http_handler_free.3http.adoc[nng_http_handler_free()]|free HTTP server handler
|
||||
|xref:nng_http_handler_get_data.3http.adoc[nng_http_handler_get_data()]|return extra data for HTTP handler
|
||||
|xref:nng_http_handler_set_data.3http.adoc[nng_http_handler_set_data()]|set extra data for HTTP handler
|
||||
|xref:nng_http_handler_set_host.3http.adoc[nng_http_handler_set_host()]|set host for HTTP handler
|
||||
|xref:nng_http_handler_set_method.3http.adoc[nng_http_handler_set_method()]|set HTTP handler method
|
||||
|xref:nng_http_handler_set_tree.3http.adoc[nng_http_handler_set_tree()]|set HTTP handler to match trees
|
||||
|xref:nng_http_hijack.3http.adoc[nng_http_hijack()]|hijack HTTP server connection
|
||||
|xref:nng_http_server_add_handler.3http.adoc[nng_http_server_add_handler()]|add HTTP server handler
|
||||
|xref:nng_http_server_del_handler.3http.adoc[nng_http_server_del_handler()]|delete HTTP server handler
|
||||
|xref:nng_http_server_get_addr.3http.adoc[nng_http_server_get_addr()]|get HTTP server address
|
||||
|xref:nng_http_server_get_tls.3http.adoc[nng_http_server_get_tls()]|get HTTP server TLS configuration
|
||||
|xref:nng_http_server_hold.3http.adoc[nng_http_server_hold()]|get and hold HTTP server instance
|
||||
|xref:nng_http_server_release.3http.adoc[nng_http_server_release()]|release HTTP server instance
|
||||
|xref:nng_http_server_set_error_file.3http.adoc[nng_http_server_set_error_file()]|set custom HTTP error file
|
||||
|xref:nng_http_server_set_error_page.3http.adoc[nng_http_server_set_error_page()]|set custom HTTP error page
|
||||
|xref:nng_http_server_set_tls.3http.adoc[nng_http_server_set_tls()]|set HTTP server TLS configuration
|
||||
|xref:nng_http_server_res_error.3http.adoc[nng_http_server_res_error()]|use HTTP server error page
|
||||
|xref:nng_http_server_start.3http.adoc[nng_http_server_start()]|start HTTP server
|
||||
|xref:nng_http_server_stop.3http.adoc[nng_http_server_stop()]|stop HTTP server
|
||||
|===
|
||||
|
||||
=== TLS Configuration Objects
|
||||
|
||||
The following functions are used to manipulate transport layer security
|
||||
(TLS) configuration objects. Most of these functions will not be used even
|
||||
by TLS applications.
|
||||
|
||||
NOTE: These functions will only be present if the library has been built
|
||||
with TLS support.
|
||||
|
||||
|===
|
||||
|xref:nng_tls_config_alloc.3tls.adoc[nng_tls_config_alloc()]|allocate TLS configuration
|
||||
|xref:nng_tls_config_auth_mode.3tls.adoc[nng_tls_config_auth_mode()]|set authentication mode
|
||||
|xref:nng_tls_config_ca_chain.3tls.adoc[nng_tls_config_ca_chain()]|set certificate authority chain
|
||||
|xref:nng_tls_config_ca_file.3tls.adoc[nng_tls_config_ca_file()]|load certificate authority from file
|
||||
|xref:nng_tls_config_cert_key_file.3tls.adoc[nng_tls_config_cert_key_file()]|load own certificate and key from file
|
||||
|xref:nng_tls_config_own_cert.3tls.adoc[nng_tls_config_own_cert()]|set own certificate and key
|
||||
|xref:nng_tls_config_free.3tls.adoc[nng_tls_config_free()]|free TLS configuration
|
||||
|xref:nng_tls_config_server_name.3tls.adoc[nng_tls_config_server_name()]|set remote server name
|
||||
|===
|
||||
|
||||
|
||||
== SEE ALSO
|
||||
|
||||
[.text-left]
|
||||
xref:nng_compat.3compat.adoc[nng_compat(3compat)],
|
||||
xref:nng.7.adoc[nng(7)]
|
2
external/nng/docs/man/man1.desc
vendored
Normal file
2
external/nng/docs/man/man1.desc
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
This section documents utilities and programs that are included
|
||||
with the distribution.
|
1
external/nng/docs/man/man1.sect
vendored
Normal file
1
external/nng/docs/man/man1.sect
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
Commands and Utilities
|
6
external/nng/docs/man/man3.desc
vendored
Normal file
6
external/nng/docs/man/man3.desc
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
This section documents core libary functions supporting Scalability
|
||||
Protocols.
|
||||
|
||||
Most Scalability Protocols applications can be written using just
|
||||
the functions documented in this section, as this represents the
|
||||
primary API for building such applications.
|
1
external/nng/docs/man/man3.sect
vendored
Normal file
1
external/nng/docs/man/man3.sect
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
Library Functions
|
13
external/nng/docs/man/man3compat.desc
vendored
Normal file
13
external/nng/docs/man/man3compat.desc
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
This section documents the _nanomsg_ 1.0 libary compatible functions.
|
||||
|
||||
These functions are provided as a transition aid, for application
|
||||
developers coming to _NNG_ from _libnanomsg_, and are discouraged
|
||||
from use in new applications.
|
||||
|
||||
TIP: While this is discouraged for long term use, as a transition aid
|
||||
applications may use the value returned by the
|
||||
xref:nng_socket_id.3.adoc[`nng_socket_id()`] in these functions just like a
|
||||
socket descriptor (as if the socket were opened via
|
||||
xref:nn_socket.3compat.adoc[`nn_socket()`]).
|
||||
This sort of API intermixing should only be used during transition from
|
||||
the legacy API to the new API.
|
1
external/nng/docs/man/man3compat.sect
vendored
Normal file
1
external/nng/docs/man/man3compat.sect
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
Compatible Library Functions
|
13
external/nng/docs/man/man3http.desc
vendored
Normal file
13
external/nng/docs/man/man3http.desc
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
This section documents supplemental HTTP (HyperText Transport Protocol)
|
||||
support functions that are available.
|
||||
|
||||
These functions can be used in conjunction with the
|
||||
xref:nng_ws.7.adoc[WebSocket] transport for Scalability Protocols, or they
|
||||
may be used to construct other types of applications that communicate
|
||||
using HTTP.
|
||||
|
||||
It is also possible to combine the two, such that an HTTP server providing
|
||||
static or dynamic content can also be used to host one or more Scalability
|
||||
Protocols sockets.
|
||||
|
||||
NOTE: At present NNG only supports HTTP/1.0 and HTTP/1.1.
|
1
external/nng/docs/man/man3http.sect
vendored
Normal file
1
external/nng/docs/man/man3http.sect
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
Supplemental HTTP Functions
|
7
external/nng/docs/man/man3str.desc
vendored
Normal file
7
external/nng/docs/man/man3str.desc
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
This section documents supplemental byte stream functions that
|
||||
are available.
|
||||
|
||||
These functions are made available to facilitate using raw byte stream
|
||||
connections with the NNG asynchronous I/O API.
|
||||
These byte streams may be useful for applications that need to
|
||||
communicate with raw TCP/IP or IPC streams instead of Scalability Protocols.
|
1
external/nng/docs/man/man3str.sect
vendored
Normal file
1
external/nng/docs/man/man3str.sect
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
Supplemental TCP Functions
|
7
external/nng/docs/man/man3supp.desc
vendored
Normal file
7
external/nng/docs/man/man3supp.desc
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
This section documents supplemental functions that are available.
|
||||
These functions are not intrinsic to building Scalability Protocols
|
||||
applications with this library.
|
||||
|
||||
However, their use may facilitate writing portable applications by
|
||||
providing uniform functions for common application needs such as
|
||||
mutual exclusion locks, threading, time keeping, and similar needs.
|
1
external/nng/docs/man/man3supp.sect
vendored
Normal file
1
external/nng/docs/man/man3supp.sect
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
Supplemental Functions
|
17
external/nng/docs/man/man3tls.desc
vendored
Normal file
17
external/nng/docs/man/man3tls.desc
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
This section documents supplemental TLS (Transport Layer Security)
|
||||
functions that are available.
|
||||
TLS support is available when using Scalability Protocols with
|
||||
the xref:nng_tls.7.adoc[TLS] transport, or when using WebSocket, either
|
||||
with the xref:nng_ws.7.adoc[WebSocket] transport for Scalability Protocols,
|
||||
or combined with other HTTP capabilities.
|
||||
|
||||
These functions depend on library support that is not included directly
|
||||
with _NNG_ however, so their presence will depend on whether this
|
||||
additional support was present and enabled with _libnng_ was built.
|
||||
|
||||
Currently, this extra support can be provided by the
|
||||
https://tls.mbed.org[mbedTLS library] or by external plug-ins.
|
||||
|
||||
TIP: Contact https://staysail.tech[Staysail Systems, Inc.] for
|
||||
details about commercially available options, including support for
|
||||
FIPS 140-2 validated cryptography and TLS v1.3.
|
1
external/nng/docs/man/man3tls.sect
vendored
Normal file
1
external/nng/docs/man/man3tls.sect
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
Supplemental TLS Functions
|
4
external/nng/docs/man/man5.desc
vendored
Normal file
4
external/nng/docs/man/man5.desc
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
This section documents core macros and types that are available.
|
||||
|
||||
These are the core types and macros that most Scalabilty Protocols
|
||||
applications need will use.
|
1
external/nng/docs/man/man5.sect
vendored
Normal file
1
external/nng/docs/man/man5.sect
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
Macros and Types
|
14
external/nng/docs/man/man7.desc
vendored
Normal file
14
external/nng/docs/man/man7.desc
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
This sections documents various protocols and transports that are
|
||||
available in the distribution.
|
||||
|
||||
(((protocol)))
|
||||
Protocols implement communication patterns, such as
|
||||
request/reply, publish/subscribe, and so forth.
|
||||
A given xref:nng_socket.5.adoc[socket] is created with exactly one protocol, and that
|
||||
protocol defines the key behavior of the socket.
|
||||
|
||||
(((transport)))
|
||||
Conversely, transports are the underlying mechansims by which messages
|
||||
are moved between participants, such as TCP/IP or UNIX domain IPC.
|
||||
A given xref:nng_socket.5.adoc[socket] may be using several transports at the same
|
||||
time.
|
1
external/nng/docs/man/man7.sect
vendored
Normal file
1
external/nng/docs/man/man7.sect
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
Protocols and Transports
|
67
external/nng/docs/man/nn_allocmsg.3compat.adoc
vendored
Normal file
67
external/nng/docs/man/nn_allocmsg.3compat.adoc
vendored
Normal file
|
@ -0,0 +1,67 @@
|
|||
= nn_allocmsg(3compat)
|
||||
//
|
||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
|
||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||||
//
|
||||
// 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
|
||||
|
||||
nn_allocmsg - allocate message (compatible API)
|
||||
|
||||
== SYNOPSIS
|
||||
|
||||
[source,c]
|
||||
----
|
||||
#include <nanomsg/nn.h>
|
||||
|
||||
void *nn_allocmsg(size_t size, int type);
|
||||
----
|
||||
|
||||
== DESCRIPTION
|
||||
|
||||
The `nn_allocmsg()` allocates a message structure of size _size_, and is
|
||||
primarily used to support zero-copy send operations, making use of the
|
||||
`NNG_MSG` special size indicator.
|
||||
The value returned is a pointer to the start of the message payload buffer.
|
||||
|
||||
The value of _size_ must be positive, and small enough to hold reasonable
|
||||
message data plus book-keeping information.
|
||||
|
||||
NOTE: This function is provided for API
|
||||
xref:nng_compat.3compat.adoc[compatibility] with legacy _libnanomsg_.
|
||||
Consider using the relevant xref:libnng.3.adoc[modern API] instead.
|
||||
|
||||
The value of _type_ *must* be zero.
|
||||
(This argument was reserved to support different kinds of memory spaces
|
||||
for RDMA devices, but this was never developed in the legacy API.)
|
||||
|
||||
The returned message must be disposed of by either
|
||||
xref:nn_freemsg.3compat.adoc[`nn_freemsg()`] or
|
||||
xref:nn_send.3compat.adoc[`nn_send()`] when the caller is finished with it.
|
||||
|
||||
== RETURN VALUES
|
||||
|
||||
This function returns a pointer to message buffer space, or `NULL`
|
||||
on failure.
|
||||
|
||||
== ERRORS
|
||||
|
||||
[horizontal]
|
||||
`ENOMEM`:: Insufficient memory is available.
|
||||
`EINVAL`:: An invalid _size_ or _type_ was specified.
|
||||
`ETERM`:: The library is shutting down.
|
||||
|
||||
== SEE ALSO
|
||||
|
||||
[.text-left]
|
||||
xref:nn_errno.3compat.adoc[nn_errno(3compat)],
|
||||
xref:nn_freemsg.3compat.adoc[nn_freemsg(3compat)],
|
||||
xref:nn_reallocmsg.3compat.adoc[nn_reallocmsg(3compat)],
|
||||
xref:nn_send.3compat.adoc[nn_send(3compat)],
|
||||
xref:nng_compat.3compat.adoc[nng_compat(3compat)],
|
||||
xref:nng.7.adoc[nng(7)]
|
68
external/nng/docs/man/nn_bind.3compat.adoc
vendored
Normal file
68
external/nng/docs/man/nn_bind.3compat.adoc
vendored
Normal file
|
@ -0,0 +1,68 @@
|
|||
= nn_bind(3compat)
|
||||
//
|
||||
// Copyright 2020 Staysail Systems, Inc. <info@staysail.tech>
|
||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||||
//
|
||||
// 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
|
||||
|
||||
nn_bind - accept connections from remote peers (compatible API)
|
||||
|
||||
== SYNOPSIS
|
||||
|
||||
[source, c]
|
||||
----
|
||||
#include <nanomsg/nn.h>
|
||||
|
||||
int nn_bind(int sock, const char *url)
|
||||
----
|
||||
|
||||
== DESCRIPTION
|
||||
|
||||
The `nn_bind()` function arranges for the socket _sock_ to
|
||||
accept connections at the address specified by _url_.
|
||||
An identifier for this socket's association with the _url_ is
|
||||
returned to the caller on success.
|
||||
This identfier can be used with
|
||||
xref:nn_shutdown.3compat.adoc[`nn_shutdown()`] to
|
||||
remove the association later.
|
||||
|
||||
NOTE: This function is provided for API
|
||||
xref:nng_compat.3compat.adoc[compatibility] with legacy _libnanomsg_.
|
||||
Consider using the relevant xref:libnng.3.adoc[modern API] instead.
|
||||
|
||||
NOTE: The bind operation is performed asynchronously, and may not have
|
||||
completed before this function returns control to the caller.
|
||||
|
||||
IMPORTANT: Only transports supported by legacy _libnanomsg_ may be
|
||||
used with this function.
|
||||
In particular, only the schemes `tcp://`, `ipc://`, `inproc://`, and `ws://` are
|
||||
supported with this function.
|
||||
(Use the xref:libnng.3.adoc[modern API] to use other schemes.)
|
||||
|
||||
== RETURN VALUES
|
||||
|
||||
This function returns a positive identifier on success, and -1 on error.
|
||||
|
||||
== ERRORS
|
||||
|
||||
[horizontal]
|
||||
`EADDRINUSE`:: The address specified by _url_ is already in use.
|
||||
`EADDRNOTAVAIL`:: The address specified by _url_ is not available.
|
||||
`EBADF`:: The socket _sock_ is not open.
|
||||
`EINVAL`:: An invalid _url_ was supplied.
|
||||
|
||||
== SEE ALSO
|
||||
|
||||
[.text-left]
|
||||
xref:nn_connect.3compat.adoc[nn_connect(3compat)],
|
||||
xref:nn_errno.3compat.adoc[nn_errno(3compat)],
|
||||
xref:nn_shutdown.3compat.adoc[nn_shutdown(3compat)],
|
||||
xref:nn_socket.3compat.adoc[nn_socket(3compat)],
|
||||
xref:nng_compat.3compat.adoc[nn_compat(3compat)],
|
||||
xref:nng.7.adoc[nng(7)]
|
51
external/nng/docs/man/nn_close.3compat.adoc
vendored
Normal file
51
external/nng/docs/man/nn_close.3compat.adoc
vendored
Normal file
|
@ -0,0 +1,51 @@
|
|||
= nn_close(3compat)
|
||||
//
|
||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
|
||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||||
//
|
||||
// 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
|
||||
|
||||
nn_close - close socket (compatible API)
|
||||
|
||||
== SYNOPSIS
|
||||
|
||||
[source,c]
|
||||
----
|
||||
#include <nanomsg/nn.h>
|
||||
|
||||
int nn_close(int sock);
|
||||
----
|
||||
|
||||
== DESCRIPTION
|
||||
|
||||
The `nn_close()` function closes the socket _sock_.
|
||||
Any operations that are currently in progress will be terminated, and will
|
||||
fail with error `EBADF`.
|
||||
|
||||
NOTE: This function is provided for API
|
||||
xref:nng_compat.3compat.adoc[compatibility] with legacy _libnanomsg_.
|
||||
Consider using the relevant xref:libnng.3.adoc[modern API] instead.
|
||||
|
||||
== RETURN VALUES
|
||||
|
||||
This function returns zero on success, and -1 on failure.
|
||||
|
||||
== ERRORS
|
||||
|
||||
[horizontal]
|
||||
`EBADF`:: The socket is not open.
|
||||
`ETERM`:: The library is shutting down.
|
||||
|
||||
== SEE ALSO
|
||||
|
||||
[.text-left]
|
||||
xref:nn_errno.3compat.adoc[nn_errno(3compat)],
|
||||
xref:nn_socket.3compat.adoc[nn_socket(3compat)],
|
||||
xref:nng_compat.3compat.adoc[nng_compat(3compat)],
|
||||
xref:nng.7.adoc[nng(7)]
|
78
external/nng/docs/man/nn_cmsg.3compat.adoc
vendored
Normal file
78
external/nng/docs/man/nn_cmsg.3compat.adoc
vendored
Normal file
|
@ -0,0 +1,78 @@
|
|||
= nn_cmsg(3compat)
|
||||
//
|
||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
|
||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||||
//
|
||||
// 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
|
||||
|
||||
nn_cmsg - message control data (compatible API)
|
||||
|
||||
== SYNOPSIS
|
||||
|
||||
[source,c]
|
||||
----
|
||||
#include <nanomsg/nn.h>
|
||||
|
||||
struct nn_cmsghdr {
|
||||
size_t cmsg_len;
|
||||
int cmsg_level;
|
||||
int cmsg_type;
|
||||
};
|
||||
----
|
||||
|
||||
== DESCRIPTION
|
||||
|
||||
The `nn_cmsghdr` structure describes a block of control data that is
|
||||
associated with a message either sent by xref:nn_sendmsg.3compat.adoc[`nn_sendmsg()`]
|
||||
or received by xref:nn_recvmsg.3compat.adoc[`nn_recvmsg()`].
|
||||
|
||||
NOTE: This structure and supporting macros are provided for API
|
||||
xref:nng_compat.3compat.adoc[compatibility] with legacy _libnanomsg_.
|
||||
Consider using the relevant xref:libnng.3.adoc[modern API] instead.
|
||||
|
||||
Each header is followed by `cmsg_len` bytes of data, plus any padding required
|
||||
to align the structure.
|
||||
|
||||
The only defined ancillary data at this time is the protocol headers used by
|
||||
the protocols.
|
||||
This uses `cmsg_level` set to `PROTO_SP` and the `cmsg_type` set to
|
||||
`SP_HDR`.
|
||||
The actual data for this will vary from depending on the protocol used.
|
||||
|
||||
Convenience macros are provided to make working with these fields easier.
|
||||
|
||||
`struct nn_cmsghdr *NN_CMSG_FIRSTHDR(struct nn_msghdr *__hdr__)`::
|
||||
This macro returns the first `struct nn_cmsghdr` header in _hdr_.
|
||||
|
||||
`struct nn_cmsghdr *NN_CMSG_NXTHDR(struct nn_msghdr *__hdr__, struct nn_cmsghdr *__ch__)`::
|
||||
This macro returns a pointer to the next `struct nn_cmsghdr` in _hdr_ after _ch_.
|
||||
|
||||
`void *NN_CMSG_DATA(struct nn_cmsghdr *__ch__)`::
|
||||
This macro returns a pointer to the header-specific data for _ch_.
|
||||
|
||||
`size_t NN_CMSG_ALIGN(size_t __len__)`::
|
||||
This macro returns the length specified by _len_, plus any padding required to
|
||||
provide the necessary alignment for another structure.
|
||||
|
||||
`size_t NN_CMSG_SPACE(size_t __len__)`::
|
||||
This macro returns the amount of space required for a header, with _len_
|
||||
bytes of following data, and any necessary padding.
|
||||
|
||||
`size_t NN_CMSG_LEN(size_t __len__)`::
|
||||
This macro evaluates to the length of the header (including alignment),
|
||||
and the associated data of length _len_, but without any trailing padding
|
||||
to align for another header.
|
||||
|
||||
== SEE ALSO
|
||||
|
||||
[.text-left]
|
||||
xref:nn_recvmsg.3compat.adoc[nn_recvmsg(3compat)],
|
||||
xref:nn_sendmsg.3compat.adoc[nn_sendmsg(3compat)],
|
||||
xref:nng_compat.3compat.adoc[nng_compat(3compat)],
|
||||
xref:nng.7.adoc[nng(7)]
|
67
external/nng/docs/man/nn_connect.3compat.adoc
vendored
Normal file
67
external/nng/docs/man/nn_connect.3compat.adoc
vendored
Normal file
|
@ -0,0 +1,67 @@
|
|||
= nn_connect(3compat)
|
||||
//
|
||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
|
||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||||
//
|
||||
// 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
|
||||
|
||||
nn_connect - connect to remote peer (compatible API)
|
||||
|
||||
== SYNOPSIS
|
||||
|
||||
[source, c]
|
||||
----
|
||||
#include <nanomsg/nn.h>
|
||||
|
||||
int nn_connect(int sock, const char *url)
|
||||
----
|
||||
|
||||
== DESCRIPTION
|
||||
|
||||
The `nn_connect()` function arranges for the socket _sock_ to
|
||||
initiate connection to a peer at the address specified by _url_.
|
||||
An identifier for this socket's association with the _url_ is
|
||||
returned to the caller on success.
|
||||
This identifier can be used with
|
||||
xref:nn_shutdown.3compat.adoc[`nn_shutdown()`] to
|
||||
remove the association later.
|
||||
|
||||
NOTE: This function is provided for API
|
||||
xref:nng_compat.3compat.adoc[compatibility] with legacy _libnanomsg_.
|
||||
Consider using the relevant xref:libnng.3.adoc[modern API] instead.
|
||||
|
||||
NOTE: The connect operation is performed asynchronously, and may not have
|
||||
completed before this function returns control to the caller.
|
||||
|
||||
IMPORTANT: Only transports supported by legacy _libnanomsg_ may be
|
||||
used with this function.
|
||||
In particular, only the schemes `tcp://`, `ipc://`, `inproc://`, and `ws://` are
|
||||
supported with this function.
|
||||
(Use the xref:libnng.3.adoc[modern API] to use other schemes.)
|
||||
|
||||
== RETURN VALUES
|
||||
|
||||
This function returns a positive identifier success, and -1 on error.
|
||||
|
||||
== ERRORS
|
||||
|
||||
[horizontal]
|
||||
`ECONNREFUSED`:: The connection attempt was refused.
|
||||
`EBADF`:: The socket _sock_ is not open.
|
||||
`EINVAL`:: An invalid _url_ was supplied.
|
||||
|
||||
== SEE ALSO
|
||||
|
||||
[.text-left]
|
||||
xref:nn_bind.3compat.adoc[nn_bind(3compat)],
|
||||
xref:nn_errno.3compat.adoc[nn_errno(3compat)],
|
||||
xref:nn_shutdown.3compat.adoc[nn_shutdown(3compat)],
|
||||
xref:nn_socket.3compat.adoc[nn_socket(3compat)],
|
||||
xref:nng_compat.3compat.adoc[nn_compat(3compat)],
|
||||
xref:nng.7.adoc[nng(7)]
|
59
external/nng/docs/man/nn_device.3compat.adoc
vendored
Normal file
59
external/nng/docs/man/nn_device.3compat.adoc
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
= nn_device(3compat)
|
||||
//
|
||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
|
||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||||
//
|
||||
// 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
|
||||
|
||||
nn_device - create forwarding device (compatible API)
|
||||
|
||||
== SYNOPSIS
|
||||
|
||||
[source,c]
|
||||
----
|
||||
#include <nanomsg/nn.h>
|
||||
|
||||
int nn_device(int sock1, int sock2);
|
||||
----
|
||||
|
||||
== DESCRIPTION
|
||||
|
||||
The `nn_device()` function is used to create a forwarder, where messages
|
||||
received on one of the two sockets _sock1_ and _sock2_ are forwarded to
|
||||
the other.
|
||||
|
||||
NOTE: This function is provided for API
|
||||
xref:nng_compat.3compat.adoc[compatibility] with legacy _libnanomsg_.
|
||||
Consider using the relevant xref:libnng.3.adoc[modern API] instead.
|
||||
|
||||
The two sockets must be compatible, and must be
|
||||
xref:nng.7.adoc#raw_mode[raw mode]
|
||||
sockets.
|
||||
More detail about devices and how they can be used is available in the
|
||||
new style xref:nng_device.3.adoc[nng_device()] documentation.
|
||||
|
||||
== RETURN VALUES
|
||||
|
||||
This function blocks forever, and will return -1 only when
|
||||
one of the sockets is closed or an error occurs.
|
||||
|
||||
== ERRORS
|
||||
|
||||
[horizontal]
|
||||
`EBADF`:: One of the two sockets is invalid or not open, or has
|
||||
`EINVAL`:: The sockets are not compatible with each other, or not both raw.
|
||||
`ENOMEM`:: Insufficient memory is available.
|
||||
|
||||
== SEE ALSO
|
||||
|
||||
[.text-left]
|
||||
xref:nn_errno.3compat.adoc[nn_errno(3compat)],
|
||||
xref:nn_socket.3compat.adoc[nn_socket(3compat)],
|
||||
xref:nng_compat.3compat.adoc[nng_compat(3compat)],
|
||||
xref:nng.7.adoc[nng(7)]
|
79
external/nng/docs/man/nn_errno.3compat.adoc
vendored
Normal file
79
external/nng/docs/man/nn_errno.3compat.adoc
vendored
Normal file
|
@ -0,0 +1,79 @@
|
|||
= nn_errno(3compat)
|
||||
//
|
||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
|
||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||||
//
|
||||
// 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
|
||||
|
||||
nn_errno - return most recent error (compatible API)
|
||||
|
||||
== SYNOPSIS
|
||||
|
||||
[source,c]
|
||||
----
|
||||
#include <nanomsg/nn.h>
|
||||
|
||||
int nn_errno(void);
|
||||
----
|
||||
|
||||
== DESCRIPTION
|
||||
|
||||
The `nn_errno()` function returns the error number corresponding to the
|
||||
most recent failed operation by the calling thread.
|
||||
|
||||
NOTE: This function is provided for API
|
||||
xref:nng_compat.3compat.adoc[compatibility] with legacy _libnanomsg_.
|
||||
Consider using the relevant xref:libnng.3.adoc[modern API] instead.
|
||||
|
||||
IMPORTANT: The error numbers returned from this function may include
|
||||
errors caused by system functions, which overlap the usual `errno` variable,
|
||||
and this function simply returns the value of `errno`.
|
||||
However, the values returned may include numeric values that are not
|
||||
defined by the system, but are unique to _libnanomsg_, such as `EFSM`.
|
||||
|
||||
This library implements the following error numbers, in addition to any others
|
||||
that might be set for `errno` by the underlying system:
|
||||
|
||||
|
||||
== RETURN VALUES
|
||||
|
||||
This function returns the value of `errno`.
|
||||
If no operation has failed, then this will be zero.
|
||||
|
||||
== ERRORS
|
||||
|
||||
[horizontal]
|
||||
`EINTR`:: Operation interrupted.
|
||||
`ENOMEM`:: Insufficient memory.
|
||||
`EINVAL`:: Invalid argument.
|
||||
`EBUSY`:: Resource is busy.
|
||||
`ETIMEDOUT`:: Operation timed out.
|
||||
`ECONNREFUSED`:: Connection refused by peer.
|
||||
`EBADF`:: Invalid or closed socket.
|
||||
`EAGAIN`:: Operation would block.
|
||||
`ENOTSUP`:: Protocol or option not supported.
|
||||
`EADDRINUSE`:: Requested address is already in use.
|
||||
`EFSM`:: Protocol state incorrect.
|
||||
`EPROTO`:: Protocol error.
|
||||
`EHOSTUNREACH`:: Remote peer is unreachable.
|
||||
`EADDRNOTAVAIL`:: Requested address is not available.
|
||||
`EACCES`:: Permission denied.
|
||||
`EMSGSIZE`:: Message is too large.
|
||||
`ECONNABORTED`:: Connection attempt aborted.
|
||||
`ECONNRESET`:: Connection reset by peer.
|
||||
`EEXIST`:: Resource already exists.
|
||||
`EMFILE`:: Too many open files.
|
||||
`ENOSPC`:: Insufficient persistent storage.
|
||||
|
||||
== SEE ALSO
|
||||
|
||||
[.text-left]
|
||||
xref:nn_strerror.3compat.adoc[nn_strerror(3compat)],
|
||||
xref:nng_compat.3compat.adoc[nng_compat(3compat)],
|
||||
xref:nng.7.adoc[nng(7)]
|
49
external/nng/docs/man/nn_freemsg.3compat.adoc
vendored
Normal file
49
external/nng/docs/man/nn_freemsg.3compat.adoc
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
= nn_freemsg(3compat)
|
||||
//
|
||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
|
||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||||
//
|
||||
// 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
|
||||
|
||||
nn_freemsg - free message (compatible API)
|
||||
|
||||
== SYNOPSIS
|
||||
|
||||
[source,c]
|
||||
----
|
||||
#include <nanomsg/nn.h>
|
||||
|
||||
int nn_freemsg(void *msg);
|
||||
----
|
||||
|
||||
== DESCRIPTION
|
||||
|
||||
The `nn_freemsg()` deallocates a message previously allocated with
|
||||
xref:nn_allocmsg.3compat.adoc[`nn_allocmsg()`] or similar functions.
|
||||
|
||||
NOTE: This function is provided for API
|
||||
xref:nng_compat.3compat.adoc[compatibility] with legacy _libnanomsg_.
|
||||
Consider using the relevant xref:libnng.3.adoc[modern API] instead.
|
||||
|
||||
== RETURN VALUES
|
||||
|
||||
This function always returns 0.
|
||||
|
||||
== ERRORS
|
||||
|
||||
None.
|
||||
|
||||
== SEE ALSO
|
||||
|
||||
[.text-left]
|
||||
xref:nn_allocmsg.3compat.adoc[nn_allocmsg(3compat)],
|
||||
xref:nn_freemsg.3compat.adoc[nn_freemsg(3compat)],
|
||||
xref:nn_errno.3compat.adoc[nn_errno(3compat)],
|
||||
xref:nng_compat.3compat.adoc[nng_compat(3compat)],
|
||||
xref:nng.7.adoc[nng(7)]
|
46
external/nng/docs/man/nn_get_statistic.3compat.adoc
vendored
Normal file
46
external/nng/docs/man/nn_get_statistic.3compat.adoc
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
= nn_get_statistic(3compat)
|
||||
//
|
||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
|
||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||||
//
|
||||
// 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
|
||||
|
||||
nn_get_statistic - get statistic (stub)
|
||||
|
||||
== SYNOPSIS
|
||||
|
||||
[source,c]
|
||||
----
|
||||
#include <nanomsg/nn.h>
|
||||
|
||||
uint64_t nn_get_statistic(int sock, int stat);
|
||||
----
|
||||
|
||||
== DESCRIPTION
|
||||
|
||||
The `nn_get_statistic()` function exists only as a stub, and always returns
|
||||
zero.
|
||||
|
||||
NOTE: This function is provided for API
|
||||
xref:nng_compat.3compat.adoc[compatibility] with legacy _libnanomsg_.
|
||||
Consider using the relevant xref:libnng.3.adoc[modern API] instead.
|
||||
|
||||
== RETURN VALUES
|
||||
|
||||
Zero.
|
||||
|
||||
== ERRORS
|
||||
|
||||
None.
|
||||
|
||||
== SEE ALSO
|
||||
|
||||
[.text-left]
|
||||
xref:nng_compat.3compat.adoc[nng_compat(3compat)],
|
||||
xref:nng.7.adoc[nng(7)]
|
228
external/nng/docs/man/nn_getsockopt.3compat.adoc
vendored
Normal file
228
external/nng/docs/man/nn_getsockopt.3compat.adoc
vendored
Normal file
|
@ -0,0 +1,228 @@
|
|||
= nn_getsockopt(3compat)
|
||||
//
|
||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
|
||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||||
//
|
||||
// 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
|
||||
|
||||
nn_getsockopt - get socket option (compatible API)
|
||||
|
||||
== SYNOPSIS
|
||||
|
||||
[source,c]
|
||||
----
|
||||
#include <nanomsg/nn.h>
|
||||
|
||||
int nn_getsockopt(int sock, int level, int option, void *val, size_t *szp);
|
||||
----
|
||||
|
||||
== DESCRIPTION
|
||||
|
||||
The `nn_getsockopt()` function gets a socket option on socket _sock_.
|
||||
The option retrieved is determined by the _level_ and _option_.
|
||||
|
||||
NOTE: This function is provided for API
|
||||
xref:nng_compat.3compat.adoc[compatibility] with legacy _libnanomsg_.
|
||||
Consider using the relevant xref:libnng.3.adoc[modern API] instead.
|
||||
|
||||
The value pointed to by _szp_ must be initialized to the size of the buffer
|
||||
pointed to by _val_.
|
||||
No more than this many bytes of the option will be copied into the destination
|
||||
buffer on success.
|
||||
On success, the value pointed to by _szp_ will be updated with the actual
|
||||
size of the option.
|
||||
|
||||
TIP: To determine the size to receive an option, first call this function
|
||||
with _val_ set to `NULL` and the value addressed by _szp_ initialized to zero.
|
||||
|
||||
The _level_ determines whether the option is a generic socket option,
|
||||
or is transport-specific.
|
||||
The values possible for level are as follows:
|
||||
|
||||
[horizontal]
|
||||
`NN_SOL_SOCKET`:: Generic socket option
|
||||
`NN_IPC`:: Transport specific option for IPC.
|
||||
`NN_TCP`:: Transport specific option for TCP.
|
||||
`NN_WS`:: Transport specific option for WebSocket.
|
||||
|
||||
The following generic socket options are possible (all are of type `int` and
|
||||
thus size 4, unless otherwise indicated.)
|
||||
|
||||
`NN_SNDBUF`::
|
||||
Send buffer size in bytes.
|
||||
|
||||
NOTE: In _NNG_ buffers are sized as a count of messages rather than
|
||||
bytes; accordingly this value is the queue depth multiplied by 1024
|
||||
(representing an estimate that the average message size is 1kB).
|
||||
Applications that have unusual message sizes may wish to adjust the value
|
||||
used here accordingly.
|
||||
|
||||
`NN_RCVBUF`::
|
||||
Receive buffer size in bytes.
|
||||
|
||||
NOTE: The same caveats for `NN_SNDBUF` apply here as well.
|
||||
|
||||
`NN_SNDTIMEO`::
|
||||
Send time-out in milliseconds.
|
||||
Send operations will fail with `ETIMEDOUT` if no message can be received
|
||||
after this many milliseconds have transpired since the operation was started.
|
||||
A value of -1 means that no timeout is applied.
|
||||
|
||||
`NN_RCVTIMEO`::
|
||||
Receive time-out in milliseconds.
|
||||
Receive operations will fail with `ETIMEDOUT` if no message can be received
|
||||
after this many milliseconds have transpired since the operation was started.
|
||||
A value of -1 means that no timeout is applied.
|
||||
|
||||
`NN_RCVMAXSIZE`::
|
||||
Maximum receive size in bytes.
|
||||
The socket will discard messages larger than this on receive.
|
||||
The default, 1MB, is intended to prevent denial-of-service attacks.
|
||||
The value -1 removes any limit.
|
||||
|
||||
`NN_RECONNECT_IVL`::
|
||||
Reconnect interval in milliseconds.
|
||||
After an outgoing connection is closed or fails, the socket will
|
||||
automatically attempt to reconnect after this many milliseconds.
|
||||
This is the starting value for the time, and is used in the first
|
||||
reconnection attempt after a successful connection is made.
|
||||
The default is 100.
|
||||
|
||||
`NN_RECONNECT_IVL_MAX`::
|
||||
Maximum reconnect interval in milliseconds.
|
||||
Subsequent reconnection attempts after a failed attempt are made at
|
||||
exponentially increasing intervals (back-off), but the interval is
|
||||
capped by this value.
|
||||
If this value is smaller than `NN_RECONNECT_IVL`, then no exponential
|
||||
back-off is performed, and each reconnect interval will be determined
|
||||
solely by `NN_RECONNECT_IVL`.
|
||||
The default is zero.
|
||||
|
||||
`NN_LINGER`::
|
||||
This option is always zero and exists only for compatibility.
|
||||
|
||||
NOTE: This option was unreliable in early releases of _libnanomsg_, and
|
||||
is unsupported in _NNG_ and recent _libnanomsg_ releases.
|
||||
Applications needing assurance of message delivery should either include an
|
||||
explicit notification (automatic with the `NN_REQ` protocol) or allow
|
||||
sufficient time for the socket to drain before closing the socket or exiting.
|
||||
|
||||
|
||||
`NN_SNDPRIO`::
|
||||
This option is not implemented at this time.
|
||||
|
||||
`NN_RCVPRIO`::
|
||||
This option is not implemented at this time.
|
||||
|
||||
`NN_IPV4ONLY`::
|
||||
This option is not implemented at this time.
|
||||
|
||||
`NN_SOCKET_NAME`::
|
||||
This option is a string, and represents the socket name.
|
||||
It can be changed to help with identifying different sockets with
|
||||
their different application-specific purposes.
|
||||
|
||||
`NN_MAXTTL`::
|
||||
Maximum number of times a message may traverse devices or proxies.
|
||||
This value, if positive, provides some protection against forwarding loops in
|
||||
xref:nng_device.3.adoc[device] chains.
|
||||
|
||||
NOTE: Not all protocols offer this protection, so care should still be used
|
||||
in configuring device forwarding.
|
||||
|
||||
`NN_DOMAIN`::
|
||||
This option of type `int` represents either the value `AF_SP` or `AF_SP_RAW`,
|
||||
corresponding to the value that the socket was created with.
|
||||
|
||||
`NN_PROTOCOL`::
|
||||
This option option of type `int` contains the numeric protocol number
|
||||
that the socket is used with.
|
||||
|
||||
`NN_RCVFD`::
|
||||
This option returns a file descriptor suitable for use in with `poll()` or
|
||||
`select()` (or other system-specific polling functions).
|
||||
This descriptor will be readable when a message is available for receiving
|
||||
at the socket.
|
||||
This option is of type `int` on all systems except Windows, where it is of
|
||||
type `SOCKET`.
|
||||
|
||||
NOTE: The file descriptor should not be read or written by the application,
|
||||
and is not the same as any underlying descriptor used for network sockets.
|
||||
|
||||
`NN_SNDFD`::
|
||||
This option returns a file descriptor suitable for use in with `poll()` or
|
||||
`select()` (or other system-specific polling functions).
|
||||
This descriptor will be readable when the socket is able to accept a message
|
||||
for sending.
|
||||
This option is of type `int` on all systems except Windows, where it is of
|
||||
type `SOCKET`.
|
||||
|
||||
NOTE: The file descriptor should not be read or written by the application,
|
||||
and is not the same as any underlying descriptor used for network sockets.
|
||||
Furthermore, the file descriptor should only be polled for _readability_.
|
||||
|
||||
The following option is available for `NN_REQ` sockets
|
||||
using the `NN_REQ` level:
|
||||
|
||||
`NN_REQ_RESEND_IVL`::
|
||||
Request retry interval in milliseconds.
|
||||
If an `NN_REQ` socket does not receive a reply to a request within this
|
||||
period of time, the socket will automatically resend the request.
|
||||
The default value is 60000 (one minute).
|
||||
|
||||
The following option is available for `NN_SURVEYOR` sockets
|
||||
using the `NN_SURVEYOR` level:
|
||||
|
||||
`NN_SURVEYOR_DEADLINE`::
|
||||
Survey deadline in milliseconds for `NN_SURVEYOR` sockets.
|
||||
After sending a survey message, the socket will only accept responses
|
||||
from respondents for this long.
|
||||
Any responses arriving after this expires are silently discarded.
|
||||
|
||||
In addition, the following transport specific options are offered:
|
||||
|
||||
`NN_IPC_SEC_ATTR`::
|
||||
This `NN_IPC` option is not supported at this time.
|
||||
|
||||
`NN_IPC_OUTBUFSZ`::
|
||||
This `NN_IPC` option is not supported at this time.
|
||||
|
||||
`NN_IPC_INBUFSZE`::
|
||||
This `NN_IPC` option is not supported at this time.
|
||||
|
||||
`NN_TCP_NODELAY`::
|
||||
This `NN_TCP` option is not supported at this time.
|
||||
|
||||
`NN_WS_MSG_TYPE`::
|
||||
This `NN_WS` option is not supported, as _NNG_ only supports binary messages
|
||||
in this implementation.
|
||||
|
||||
== RETURN VALUES
|
||||
|
||||
This function returns zero on success, and -1 on failure.
|
||||
|
||||
== ERRORS
|
||||
|
||||
[horizontal]
|
||||
`EBADF`:: The socket _sock_ is not an open socket.
|
||||
`ENOMEM`:: Insufficient memory is available.
|
||||
`ENOPROTOOPT`:: The level and/or option is invalid.
|
||||
`EINVAL`:: The option, or the value passed, is invalid.
|
||||
`ETERM`:: The library is shutting down.
|
||||
`EACCES`:: The option cannot be changed.
|
||||
|
||||
== SEE ALSO
|
||||
|
||||
[.text-left]
|
||||
xref:nng_socket.5.adoc[nng_socket(5)],
|
||||
xref:nn_close.3compat.adoc[nn_close(3compat)],
|
||||
xref:nn_errno.3compat.adoc[nn_errno(3compat)],
|
||||
xref:nn_getsockopt.3compat.adoc[nn_getsockopt(3compat)],
|
||||
xref:nng_compat.3compat.adoc[nng_compat(3compat)],
|
||||
xref:nng.7.adoc[nng(7)]
|
102
external/nng/docs/man/nn_poll.3compat.adoc
vendored
Normal file
102
external/nng/docs/man/nn_poll.3compat.adoc
vendored
Normal file
|
@ -0,0 +1,102 @@
|
|||
= nn_poll(3compat)
|
||||
//
|
||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
|
||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||||
//
|
||||
// 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
|
||||
|
||||
nn_poll - poll sockets (compatible API)
|
||||
|
||||
== SYNOPSIS
|
||||
|
||||
[source, c]
|
||||
----
|
||||
#include <nanomsg/nn.h>
|
||||
|
||||
#define NN_POLLIN 1
|
||||
#define NN_POLLOUT 2
|
||||
|
||||
struct nn_pollfd {
|
||||
int fd;
|
||||
uint16_t events;
|
||||
uint16_t revents;
|
||||
};
|
||||
|
||||
int nn_poll(struct nn_pollfd *pfds, int npfd, int timeout);
|
||||
----
|
||||
|
||||
== DESCRIPTION
|
||||
|
||||
The `nn_poll()` function polls a group of sockets for readiness to send or receive.
|
||||
|
||||
NOTE: This function is provided for API
|
||||
xref:nng_compat.3compat.adoc[compatibility] with legacy _libnanomsg_.
|
||||
Consider using the relevant xref:libnng.3.adoc[modern API] instead.
|
||||
|
||||
The array of _nfds_ sockets to poll for are passed into _pfds_.
|
||||
Each member of this array is initialized with the `fd` field set to
|
||||
the socket, and the `events` field set to a mask that can contain either or both
|
||||
of the flags `NN_POLLIN` and `NN_POLLOUT`.
|
||||
|
||||
The flag `NN_POLLIN` indicates that a socket is ready for receiving without
|
||||
blocking (a message is available on the socket), and the flag `NN_POLLOUT`
|
||||
indicates that a socket is ready for sending without blocking.
|
||||
|
||||
Upon success, the function returns the number of updates the `revents`
|
||||
field of each member of the _pfds_ array, setting it to indicate
|
||||
whether the requested status is true or not.
|
||||
|
||||
NOTE: The `revents` field will only have a flag set if the corresponding
|
||||
flag was also set in the `events` field.
|
||||
|
||||
If the _timeout_ field is positive, then this function will wait for
|
||||
up the that many milliseconds.
|
||||
If none of the requested events occurs before that timeout occurs, then
|
||||
the function will return -1 and set the error to `ETIMEDOUT`.
|
||||
|
||||
If the _timeout_ is zero, then this function will return immediately,
|
||||
after updating the current status of the sockets.
|
||||
|
||||
If the _timeout_ is -1, then the function waits forever, or until one of the
|
||||
requested events occurs.
|
||||
|
||||
IMPORTANT: This function is only suitable for use with sockets obtained with the
|
||||
xref:nn_socket.3compat.adoc[`nn_socket()`] function, and is not compatible
|
||||
with file descriptors obtained via any other means.
|
||||
This includes file descriptors obtained using the `NN_SNDFD` or `NN_RCVFD`
|
||||
options with xref:nn_getsockopt.3compat.adoc[`nn_getsockopt()`]
|
||||
|
||||
NOTE: This function is significantly less efficient than other polling
|
||||
or asynchronous I/O mechanisms, and is provided for API compatibility only.
|
||||
It's use is discouraged.
|
||||
|
||||
NOTE: This function is *not* supported on systems other than POSIX derived
|
||||
platforms and Windows.
|
||||
|
||||
== RETURN VALUES
|
||||
|
||||
This function returns the number of sockets with events on success, or -1 on error.
|
||||
|
||||
== ERRORS
|
||||
|
||||
[horizontal]
|
||||
`ENOMEM`:: Insufficient memory available.
|
||||
`EBADF`:: One of the sockets is not open.
|
||||
`ETIMEDOUT`:: Operation timed out.
|
||||
`ENOTSUP`:: This function is not supported on this platform.
|
||||
|
||||
== SEE ALSO
|
||||
|
||||
[.text-left]
|
||||
xref:nn_errno.3compat.adoc[nn_errno(3compat)],
|
||||
xref:nn_recv.3compat.adoc[nn_recv(3compat)],
|
||||
xref:nn_send.3compat.adoc[nn_send(3compat)],
|
||||
xref:nn_socket.3compat.adoc[nn_socket(3compat)],
|
||||
xref:nng_compat.3compat.adoc[nn_compat(3compat)],
|
||||
xref:nng.7.adoc[nng(7)]
|
59
external/nng/docs/man/nn_reallocmsg.3compat.adoc
vendored
Normal file
59
external/nng/docs/man/nn_reallocmsg.3compat.adoc
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
= nn_reallocmsg(3compat)
|
||||
//
|
||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
|
||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||||
//
|
||||
// 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
|
||||
|
||||
nn_reallocmsg - reallocate message (compatible API)
|
||||
|
||||
== SYNOPSIS
|
||||
|
||||
[source,c]
|
||||
----
|
||||
#include <nanomsg/nn.h>
|
||||
|
||||
void *nn_reallocmsg(void *old, size_t size);
|
||||
----
|
||||
|
||||
== DESCRIPTION
|
||||
|
||||
The `nn_reallocmsg()` reallocates the message _old_, making it of size _size_.
|
||||
|
||||
NOTE: This function is provided for API
|
||||
xref:nng_compat.3compat.adoc[compatibility] with legacy _libnanomsg_.
|
||||
Consider using the relevant xref:libnng.3.adoc[modern API] instead.
|
||||
|
||||
On success, the contents of _old_ are copied into the new message
|
||||
(truncating if appropriate), then _old_ is deallocated, and a pointer
|
||||
to the new message payload is returned.
|
||||
|
||||
On failure, the _old_ message is unchanged, and the value `NULL` is returned
|
||||
to the caller.
|
||||
|
||||
== RETURN VALUES
|
||||
|
||||
This function returns a pointer to message buffer space, or `NULL`
|
||||
on failure.
|
||||
|
||||
== ERRORS
|
||||
|
||||
[horizontal]
|
||||
`ENOMEM`:: Insufficient memory is available.
|
||||
`EINVAL`:: An invalid _size_ was specified.
|
||||
`ETERM`:: The library is shutting down.
|
||||
|
||||
== SEE ALSO
|
||||
|
||||
[.text-left]
|
||||
xref:nn_allocmsg.3compat.adoc[nn_allocmsg(3compat)],
|
||||
xref:nn_freemsg.3compat.adoc[nn_freemsg(3compat)],
|
||||
xref:nn_errno.3compat.adoc[nn_errno(3compat)],
|
||||
xref:nng_compat.3compat.adoc[nng_compat(3compat)],
|
||||
xref:nng.7.adoc[nng(7)]
|
75
external/nng/docs/man/nn_recv.3compat.adoc
vendored
Normal file
75
external/nng/docs/man/nn_recv.3compat.adoc
vendored
Normal file
|
@ -0,0 +1,75 @@
|
|||
= nn_recv(3compat)
|
||||
//
|
||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
|
||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||||
//
|
||||
// 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
|
||||
|
||||
nn_recv - receive data (compatible API)
|
||||
|
||||
== SYNOPSIS
|
||||
|
||||
[source, c]
|
||||
----
|
||||
#include <nanomsg/nn.h>
|
||||
|
||||
int nn_recv(int sock, void *data, size_t size, int flags)
|
||||
----
|
||||
|
||||
== DESCRIPTION
|
||||
|
||||
The `nn_recv()` function receives a message from the socket _sock_.
|
||||
The message body must fit within _size_ bytes, and will be stored
|
||||
at the location specified by _data_, unless _size_ is the
|
||||
special value `NN_MSG`, indicating a zero-copy operation.
|
||||
|
||||
NOTE: This function is provided for API
|
||||
xref:nng_compat.3compat.adoc[compatibility] with legacy _libnanomsg_.
|
||||
Consider using the relevant xref:libnng.3.adoc[modern API] instead.
|
||||
|
||||
If _size_ has the special value `NN_MSG`, then a zero-copy operation
|
||||
is performed.
|
||||
In this case, instead of copying the message data into the address
|
||||
specified by _data_, a new message large enough to hold the message data
|
||||
will be allocated (as if by the
|
||||
function xref:nn_allocmsg.3compat.adoc[`nn_allocmsg()`]), and the message
|
||||
payload will be stored accordingly.
|
||||
In this case, the value stored at _data_ will not be message data,
|
||||
but a pointer to the message itself.
|
||||
In this case, on success, the caller shall take responsibility for
|
||||
the final disposition of the message (such as by sending it to
|
||||
another peer using xref:nn_send.3compat.adoc[`nn_send()`]) or
|
||||
xref:nn_freemsg.3compat.adoc[`nn_freemsg()`].
|
||||
|
||||
The _flags_ field may contain the special flag `NN_DONTWAIT`.
|
||||
In this case, if the no message is available for immediate receipt,
|
||||
the operation shall not block, but instead will fail with the error `EAGAIN`.
|
||||
|
||||
== RETURN VALUES
|
||||
|
||||
This function returns the number of bytes sent on success, and -1 on error.
|
||||
|
||||
== ERRORS
|
||||
|
||||
[horizontal]
|
||||
`EAGAIN`:: The operation would block.
|
||||
`EBADF`:: The socket _sock_ is not open.
|
||||
`EFSM`:: The socket cannot receive in this state.
|
||||
`ENOTSUP`:: This protocol cannot receive.
|
||||
`ETIMEDOUT`:: Operation timed out.
|
||||
|
||||
== SEE ALSO
|
||||
|
||||
[.text-left]
|
||||
xref:nn_errno.3compat.adoc[nn_errno(3compat)],
|
||||
xref:nn_recvmsg.3compat.adoc[nn_recvmsg(3compat)],
|
||||
xref:nn_send.3compat.adoc[nn_send(3compat)],
|
||||
xref:nn_socket.3compat.adoc[nn_socket(3compat)],
|
||||
xref:nng_compat.3compat.adoc[nn_compat(3compat)],
|
||||
xref:nng.7.adoc[nng(7)]
|
99
external/nng/docs/man/nn_recvmsg.3compat.adoc
vendored
Normal file
99
external/nng/docs/man/nn_recvmsg.3compat.adoc
vendored
Normal file
|
@ -0,0 +1,99 @@
|
|||
= nn_recvmsg(3compat)
|
||||
//
|
||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
|
||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||||
//
|
||||
// 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
|
||||
|
||||
nn_recvmsg - receive message (compatible API)
|
||||
|
||||
== SYNOPSIS
|
||||
|
||||
[source, c]
|
||||
----
|
||||
#include <nanomsg/nn.h>
|
||||
|
||||
int nn_recvmsg(int sock, struct nn_msghdr *hdr, int flags);
|
||||
----
|
||||
|
||||
== DESCRIPTION
|
||||
|
||||
The `nn_recvmsg()` function receives a message into the header described by
|
||||
_hdr_ using the socket _sock_.
|
||||
|
||||
NOTE: This function is provided for API
|
||||
xref:nng_compat.3compat.adoc[compatibility] with legacy _libnanomsg_.
|
||||
Consider using the relevant xref:libnng.3.adoc[modern API] instead.
|
||||
|
||||
The _flags_ field may contain the special flag `NN_DONTWAIT`.
|
||||
In this case, if no message is ready for receiving on _sock_,
|
||||
the operation shall not block, but instead will fail with the error `EAGAIN`.
|
||||
|
||||
The _hdr_ points to a structure of type `struct nn_msghdr`, which has the
|
||||
following definition:
|
||||
|
||||
[source, c]
|
||||
----
|
||||
struct nn_iovec {
|
||||
void * iov_base;
|
||||
size_t iov_len;
|
||||
};
|
||||
|
||||
struct nn_msghdr {
|
||||
struct nn_iovec *msg_iov;
|
||||
int msg_iovlen;
|
||||
void * msg_control;
|
||||
size_t msg_controllen;
|
||||
};
|
||||
----
|
||||
|
||||
The `msg_iov` is an array of scatter items, permitting the message
|
||||
to be spread into different memory blocks.
|
||||
There are `msg_iovlen` elements in this array, each of which
|
||||
has the base address (`iov_base`) and length (`iov_len`) indicated.
|
||||
|
||||
The last member of this array may have the `iov_len` field set to `NN_MSG`,
|
||||
in which case the function shall allocate a message buffer, and store the
|
||||
pointer to it at the address indicated by `iov_base`.
|
||||
This can help save an extra copy operation.
|
||||
The buffer should be deallocated by xref:nn_freemsg.3compat.adoc[`nn_freemsg()`]
|
||||
or similar when it is no longer needed.
|
||||
|
||||
The values of `msg_control` and `msg_controllen` describe a buffer
|
||||
of ancillary data associated with the message.
|
||||
This is currently only useful to obtain the message headers
|
||||
used with xref:nng.7.adoc#raw_mode[raw mode] sockets.
|
||||
In all other circumstances these fields should be zero.
|
||||
Details about this structure are covered in
|
||||
xref:nn_cmsg.3compat.adoc[`nn_cmsg(3compat)`].
|
||||
|
||||
== RETURN VALUES
|
||||
|
||||
This function returns the number of bytes received on success, and -1 on error.
|
||||
|
||||
== ERRORS
|
||||
|
||||
[horizontal]
|
||||
`EAGAIN`:: The operation would block.
|
||||
`EBADF`:: The socket _sock_ is not open.
|
||||
`EFSM`:: The socket cannot receive in this state.
|
||||
`EINVAL`:: The _hdr_ is invalid.
|
||||
`ENOTSUP`:: This protocol cannot receive.
|
||||
`ETIMEDOUT`:: Operation timed out.
|
||||
|
||||
== SEE ALSO
|
||||
|
||||
[.text-left]
|
||||
xref:nn_cmsg.3compat.adoc[nn_cmsg(3compat)],
|
||||
xref:nn_errno.3compat.adoc[nn_errno(3compat)],
|
||||
xref:nn_recv.3compat.adoc[nn_recv(3compat)],
|
||||
xref:nn_send.3compat.adoc[nn_send(3compat)],
|
||||
xref:nn_socket.3compat.adoc[nn_socket(3compat)],
|
||||
xref:nng_compat.3compat.adoc[nn_compat(3compat)],
|
||||
xref:nng.7.adoc[nng(7)]
|
74
external/nng/docs/man/nn_send.3compat.adoc
vendored
Normal file
74
external/nng/docs/man/nn_send.3compat.adoc
vendored
Normal file
|
@ -0,0 +1,74 @@
|
|||
= nn_send(3compat)
|
||||
//
|
||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
|
||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||||
//
|
||||
// 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
|
||||
|
||||
nn_send - send data (compatible API)
|
||||
|
||||
== SYNOPSIS
|
||||
|
||||
[source, c]
|
||||
----
|
||||
#include <nanomsg/nn.h>
|
||||
|
||||
int nn_send(int sock, const void *data, size_t size, int flags)
|
||||
----
|
||||
|
||||
== DESCRIPTION
|
||||
|
||||
The `nn_send()` function creates a message containing _data_ (of size _size_),
|
||||
and sends using the socket _sock_.
|
||||
|
||||
NOTE: This function is provided for API
|
||||
xref:nng_compat.3compat.adoc[compatibility] with legacy _libnanomsg_.
|
||||
Consider using the relevant xref:libnng.3.adoc[modern API] instead.
|
||||
|
||||
If _size_ has the special value `NN_MSG`, then a zero-copy operation
|
||||
is performed.
|
||||
In this case, _data_ points not to the message content itself, but instead
|
||||
is a pointer to the pointer, an extra level of pointer indirection.
|
||||
The message must have been previously allocated by
|
||||
xref:nn_allocmsg.3compat.adoc[`nn_allocmsg()`] or
|
||||
xref:nn_recvmsg.3compat.adoc[`nn_recvmsg()`]`, using the same `NN_MSG` size.
|
||||
In this case, the ownership of the message shall remain with
|
||||
the caller, unless the function returns 0, indicating that the
|
||||
function has taken responsibility for delivering or disposing of the
|
||||
message.
|
||||
|
||||
The _flags_ field may contain the special flag `NN_DONTWAIT`.
|
||||
In this case, if the socket is unable to accept more data for sending,
|
||||
the operation shall not block, but instead will fail with the error `EAGAIN`.
|
||||
|
||||
NOTE: The send operation is performed asynchronously, and may not have
|
||||
completed before this function returns control to the caller.
|
||||
|
||||
== RETURN VALUES
|
||||
|
||||
This function returns the number of bytes sent on success, and -1 on error.
|
||||
|
||||
== ERRORS
|
||||
|
||||
[horizontal]
|
||||
`EAGAIN`:: The operation would block.
|
||||
`EBADF`:: The socket _sock_ is not open.
|
||||
`EFSM`:: The socket cannot send in this state.
|
||||
`ENOTSUP`:: This protocol cannot send.
|
||||
`ETIMEDOUT`:: Operation timed out.
|
||||
|
||||
== SEE ALSO
|
||||
|
||||
[.text-left]
|
||||
xref:nn_errno.3compat.adoc[nn_errno(3compat)],
|
||||
xref:nn_recv.3compat.adoc[nn_recv(3compat)],
|
||||
xref:nn_sendmsg.3compat.adoc[nn_sendmsg(3compat)],
|
||||
xref:nn_socket.3compat.adoc[nn_socket(3compat)],
|
||||
xref:nng_compat.3compat.adoc[nn_compat(3compat)],
|
||||
xref:nng.7.adoc[nng(7)]
|
107
external/nng/docs/man/nn_sendmsg.3compat.adoc
vendored
Normal file
107
external/nng/docs/man/nn_sendmsg.3compat.adoc
vendored
Normal file
|
@ -0,0 +1,107 @@
|
|||
= nn_sendmsg(3compat)
|
||||
//
|
||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
|
||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||||
//
|
||||
// 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
|
||||
|
||||
nn_sendmsg - send message (compatible API)
|
||||
|
||||
== SYNOPSIS
|
||||
|
||||
[source, c]
|
||||
----
|
||||
#include <nanomsg/nn.h>
|
||||
|
||||
int nn_sendmsg(int sock, const struct nn_msghdr *hdr, int flags);
|
||||
----
|
||||
|
||||
== DESCRIPTION
|
||||
|
||||
The `nn_sendmsg()` function sends the message described by _hdr_ using the
|
||||
socket _sock_.
|
||||
|
||||
NOTE: This function is provided for API
|
||||
xref:nng_compat.3compat.adoc[compatibility] with legacy _libnanomsg_.
|
||||
Consider using the relevant xref:libnng.3.adoc[modern API] instead.
|
||||
|
||||
The _flags_ field may contain the special flag `NN_DONTWAIT`.
|
||||
In this case, if the socket is unable to accept more data for sending,
|
||||
the operation shall not block, but instead will fail with the error `EAGAIN`.
|
||||
|
||||
The _hdr_ points to a structure of type `struct nn_msghdr`, which has the
|
||||
following definition:
|
||||
|
||||
[source, c]
|
||||
----
|
||||
struct nn_iovec {
|
||||
void * iov_base;
|
||||
size_t iov_len;
|
||||
};
|
||||
|
||||
struct nn_msghdr {
|
||||
struct nn_iovec *msg_iov;
|
||||
int msg_iovlen;
|
||||
void * msg_control;
|
||||
size_t msg_controllen;
|
||||
};
|
||||
----
|
||||
|
||||
The `msg_iov` is an array of gather items, permitting the message
|
||||
to be spread into different memory blocks.
|
||||
There are `msg_iovlen` elements in this array, each of which
|
||||
has the base address (`iov_base`) and length (`iov_len`) indicated.
|
||||
|
||||
For buffers allocated for zero copy
|
||||
(such as by xref:nn_allocmsg.3compat.adoc[`nn_allocmsg()`]), the value
|
||||
of `iov_base` should be the address of the pointer to the buffer,
|
||||
rather than the address of the buffer itself.
|
||||
In this case, the value of `iov_len` should be `NN_MSG`,
|
||||
as the length is inferred from the allocated message.
|
||||
If the `msg_iovlen` field is `NN_MSG`, then this function will free
|
||||
the associated buffer after it is done with it, if it returns successfully.
|
||||
(If the function returns with an error, then the caller retains ownership
|
||||
of the associated buffer and may retry the operation or free the buffer
|
||||
at its choice.)
|
||||
|
||||
The values of `msg_control` and `msg_controllen` describe a buffer
|
||||
of ancillary data to send the message.
|
||||
This is currently only useful to provide the message headers
|
||||
used with xref:nng.7.adoc#raw_mode[raw mode] sockets.
|
||||
In all other circumstances these fields should be zero.
|
||||
Details about this structure are covered in
|
||||
xref:nn_cmsg.3compat.adoc[`nn_cmsg(3compat)`].
|
||||
|
||||
NOTE: The send operation is performed asynchronously, and may not have
|
||||
completed before this function returns control to the caller.
|
||||
|
||||
== RETURN VALUES
|
||||
|
||||
This function returns the number of bytes sent on success, and -1 on error.
|
||||
|
||||
== ERRORS
|
||||
|
||||
[horizontal]
|
||||
`EAGAIN`:: The operation would block.
|
||||
`EBADF`:: The socket _sock_ is not open.
|
||||
`EFSM`:: The socket cannot send in this state.
|
||||
`EINVAL`:: The _hdr_ is invalid.
|
||||
`ENOTSUP`:: This protocol cannot send.
|
||||
`ETIMEDOUT`:: Operation timed out.
|
||||
|
||||
== SEE ALSO
|
||||
|
||||
[.text-left]
|
||||
xref:nn_cmsg.3compat.adoc[nn_cmsg(3compat)],
|
||||
xref:nn_errno.3compat.adoc[nn_errno(3compat)],
|
||||
xref:nn_recv.3compat.adoc[nn_recv(3compat)],
|
||||
xref:nn_send.3compat.adoc[nn_send(3compat)],
|
||||
xref:nn_socket.3compat.adoc[nn_socket(3compat)],
|
||||
xref:nng_compat.3compat.adoc[nn_compat(3compat)],
|
||||
xref:nng.7.adoc[nng(7)]
|
205
external/nng/docs/man/nn_setsockopt.3compat.adoc
vendored
Normal file
205
external/nng/docs/man/nn_setsockopt.3compat.adoc
vendored
Normal file
|
@ -0,0 +1,205 @@
|
|||
= nn_setsockopt(3compat)
|
||||
//
|
||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
|
||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||||
//
|
||||
// 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
|
||||
|
||||
nn_setsockopt - set socket option (compatible API)
|
||||
|
||||
== SYNOPSIS
|
||||
|
||||
[source,c]
|
||||
----
|
||||
#include <nanomsg/nn.h>
|
||||
|
||||
int nn_setsockopt(int sock, int level, int option, const void *val, size_t sz);
|
||||
----
|
||||
|
||||
== DESCRIPTION
|
||||
|
||||
The `nn_setsockopt()` function sets a socket option on socket _sock_,
|
||||
affecting the behavior of the socket.
|
||||
The option set is determined by the _level_ and _option_.
|
||||
The value of the option is set by _val_, and _sz_, which are pointers to
|
||||
the actual value and the size of the value, respectively.
|
||||
|
||||
NOTE: This function is provided for API
|
||||
xref:nng_compat.3compat.adoc[compatibility] with legacy _libnanomsg_.
|
||||
Consider using the relevant xref:libnng.3.adoc[modern API] instead.
|
||||
|
||||
The _level_ determines whether the option is a generic socket option,
|
||||
or is transport-specific.
|
||||
The values possible for level are as follows:
|
||||
|
||||
[horizontal]
|
||||
`NN_SOL_SOCKET`:: Generic socket option
|
||||
`NN_IPC`:: Transport specific option for IPC.
|
||||
`NN_TCP`:: Transport specific option for TCP.
|
||||
`NN_WS`:: Transport specific option for WebSocket.
|
||||
|
||||
The following generic socket options are possible (all are of type `int` and
|
||||
thus size 4, unless otherwise indicated.)
|
||||
|
||||
`NN_SNDBUF`::
|
||||
Send buffer size in bytes.
|
||||
|
||||
NOTE: In _NNG_ buffers are sized as a count of messages rather than
|
||||
bytes, and so an attempt to estimate a conversion based upon a predetermined
|
||||
message size of 1kB is made.
|
||||
The value supplied is rounded up to the nearest value divisible by 1024, and
|
||||
then divided by 1024 to convert to a message count.
|
||||
Applications that have unusual message sizes may wish to adjust the value
|
||||
used here accordingly.
|
||||
|
||||
`NN_RCVBUF`::
|
||||
Receive buffer size in bytes.
|
||||
|
||||
NOTE: The same caveats for `NN_SNDBUF` apply here as well.
|
||||
|
||||
`NN_SNDTIMEO`::
|
||||
Send time-out in milliseconds.
|
||||
Send operations will fail with `ETIMEDOUT` if no message can be received
|
||||
after this many milliseconds have transpired since the operation was started.
|
||||
A value of -1 means that no timeout is applied.
|
||||
|
||||
`NN_RCVTIMEO`::
|
||||
Receive time-out in milliseconds.
|
||||
Receive operations will fail with `ETIMEDOUT` if no message can be received
|
||||
after this many milliseconds have transpired since the operation was started.
|
||||
A value of -1 means that no timeout is applied.
|
||||
|
||||
`NN_RCVMAXSIZE`::
|
||||
Maximum receive size in bytes.
|
||||
The socket will discard messages larger than this on receive.
|
||||
The default, 1MB, is intended to prevent denial-of-service attacks.
|
||||
The value -1 removes any limit.
|
||||
|
||||
`NN_RECONNECT_IVL`::
|
||||
Reconnect interval in milliseconds.
|
||||
After an outgoing connection is closed or fails, the socket will
|
||||
automatically attempt to reconnect after this many milliseconds.
|
||||
This is the starting value for the time, and is used in the first
|
||||
reconnection attempt after a successful connection is made.
|
||||
The default is 100.
|
||||
|
||||
`NN_RECONNECT_IVL_MAX`::
|
||||
Maximum reconnect interval in milliseconds.
|
||||
Subsequent reconnection attempts after a failed attempt are made at
|
||||
exponentially increasing intervals (back-off), but the interval is
|
||||
capped by this value.
|
||||
If this value is smaller than `NN_RECONNECT_IVL`, then no exponential
|
||||
back-off is performed, and each reconnect interval will be determined
|
||||
solely by `NN_RECONNECT_IVL`.
|
||||
The default is zero.
|
||||
|
||||
`NN_LINGER`::
|
||||
This option is ignored, and exists only for compatibility.
|
||||
|
||||
NOTE: This option was unreliable in early releases of _libnanomsg_, and
|
||||
is unsupported in _NNG_ and recent _libnanomsg_ releases.
|
||||
Applications needing assurance of message delivery should either include an
|
||||
explicit notification (automatic with the `NN_REQ` protocol) or allow
|
||||
sufficient time for the socket to drain before closing the socket or exiting.
|
||||
|
||||
`NN_SNDPRIO`::
|
||||
This option is not implemented at this time.
|
||||
|
||||
`NN_RCVPRIO`::
|
||||
This option is not implemented at this time.
|
||||
|
||||
`NN_IPV4ONLY`::
|
||||
This option is not implemented at this time.
|
||||
|
||||
`NN_SOCKET_NAME`::
|
||||
This option is a string, and represents the socket name.
|
||||
It can be changed to help with identifying different sockets with
|
||||
their different application-specific purposes.
|
||||
|
||||
`NN_MAXTTL`::
|
||||
Maximum number of times a message may traverse devices or proxies.
|
||||
This value, if positive, provides some protection against forwarding loops in
|
||||
xref:nng_device.3.adoc[device] chains.
|
||||
|
||||
NOTE: Not all protocols offer this protection, so care should still be used
|
||||
in configuring device forwarding.
|
||||
|
||||
The following option is available for `NN_REQ` sockets
|
||||
using the `NN_REQ` level:
|
||||
|
||||
`NN_REQ_RESEND_IVL`::
|
||||
Request retry interval in milliseconds.
|
||||
If an `NN_REQ` socket does not receive a reply to a request within this
|
||||
period of time, the socket will automatically resend the request.
|
||||
The default value is 60000 (one minute).
|
||||
|
||||
The following options are available for `NN_SUB` sockets using the `NN_SUB` level:
|
||||
|
||||
`NN_SUB_SUBSCRIBE`::
|
||||
Subscription topic, for `NN_SUB` sockets.
|
||||
This sets a subscription topic.
|
||||
When a message from a publisher arrives, it is compared against all
|
||||
subscriptions.
|
||||
If the first _sz_ bytes of the message are not identical to _val_,
|
||||
then the message is silently discarded.
|
||||
|
||||
TIP: To receive all messages, subscribe to an empty topic (_sz_ equal to zero).
|
||||
|
||||
`NN_SUB_UNSUBSCRIBE`::
|
||||
Removes a subscription topic that was earlier established.
|
||||
|
||||
The following option is available for `NN_SURVEYOR` sockets
|
||||
using the `NN_SURVEYOR` level:
|
||||
|
||||
`NN_SURVEYOR_DEADLINE`::
|
||||
Survey deadline in milliseconds for `NN_SURVEYOR` sockets.
|
||||
After sending a survey message, the socket will only accept responses
|
||||
from respondents for this long.
|
||||
Any responses arriving after this expires are silently discarded.
|
||||
|
||||
In addition, the following transport specific options are offered:
|
||||
|
||||
`NN_IPC_SEC_ATTR`::
|
||||
This `NN_IPC` option is not supported at this time.
|
||||
|
||||
`NN_IPC_OUTBUFSZ`::
|
||||
This `NN_IPC` option is not supported at this time.
|
||||
|
||||
`NN_IPC_INBUFSZE`::
|
||||
This `NN_IPC` option is not supported at this time.
|
||||
|
||||
`NN_TCP_NODELAY`::
|
||||
This `NN_TCP` option is not supported at this time.
|
||||
|
||||
`NN_WS_MSG_TYPE`::
|
||||
This `NN_WS` option is not supported at this time.
|
||||
|
||||
== RETURN VALUES
|
||||
|
||||
This function returns zero on success, and -1 on failure.
|
||||
|
||||
== ERRORS
|
||||
|
||||
[horizontal]
|
||||
`EBADF`:: The socket _sock_ is not an open socket.
|
||||
`ENOMEM`:: Insufficient memory is available.
|
||||
`ENOPROTOOPT`:: The level and/or option is invalid.
|
||||
`EINVAL`:: The option, or the value passed, is invalid.
|
||||
`ETERM`:: The library is shutting down.
|
||||
`EACCES`:: The option cannot be changed.
|
||||
|
||||
== SEE ALSO
|
||||
|
||||
[.text-left]
|
||||
xref:nng_socket.5.adoc[nng_socket(5)],
|
||||
xref:nn_close.3compat.adoc[nn_close(3compat)],
|
||||
xref:nn_errno.3compat.adoc[nn_errno(3compat)],
|
||||
xref:nn_getsockopt.3compat.adoc[nn_getsockopt(3compat)],
|
||||
xref:nng_compat.3compat.adoc[nng_compat(3compat)],
|
||||
xref:nng.7.adoc[nng(7)]
|
55
external/nng/docs/man/nn_shutdown.3compat.adoc
vendored
Normal file
55
external/nng/docs/man/nn_shutdown.3compat.adoc
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
= nn_shutdown(3compat)
|
||||
//
|
||||
// Copyright 2020 Staysail Systems, Inc. <info@staysail.tech>
|
||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||||
//
|
||||
// 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
|
||||
|
||||
nn_shutdown - shut down endpoint (compatible API)
|
||||
|
||||
== SYNOPSIS
|
||||
|
||||
[source, c]
|
||||
----
|
||||
#include <nanomsg/nn.h>
|
||||
|
||||
int nn_shutdown(int sock, int ep)
|
||||
----
|
||||
|
||||
== DESCRIPTION
|
||||
|
||||
The `nn_shutdown()` shuts down the endpoint _ep_, which is either a listener or
|
||||
a dialer) on the socket _sock_.
|
||||
This will stop the socket from either accepting new connections, or establishing
|
||||
old ones.
|
||||
Additionally, any established connections associated with _ep_ will be closed.
|
||||
|
||||
NOTE: This function is provided for API
|
||||
xref:nng_compat.3compat.adoc[compatibility] with legacy _libnanomsg_.
|
||||
Consider using the relevant xref:libnng.3.adoc[modern API] instead.
|
||||
|
||||
== RETURN VALUES
|
||||
|
||||
This function returns zero on success, and -1 on error.
|
||||
|
||||
== ERRORS
|
||||
|
||||
[horizontal]
|
||||
`EBADF`:: The socket _sock_ is not open.
|
||||
`EINVAL`:: An invalid _ep_ was supplied.
|
||||
|
||||
== SEE ALSO
|
||||
|
||||
[.text-left]
|
||||
xref:nn_bind.3compat.adoc[nn_bind(3compat)],
|
||||
xref:nn_connect.3compat.adoc[nn_connect(3compat)],
|
||||
xref:nn_errno.3compat.adoc[nn_errno(3compat)],
|
||||
xref:nn_socket.3compat.adoc[nn_socket(3compat)],
|
||||
xref:nng_compat.3compat.adoc[nn_compat(3compat)],
|
||||
xref:nng.7.adoc[nng(7)]
|
78
external/nng/docs/man/nn_socket.3compat.adoc
vendored
Normal file
78
external/nng/docs/man/nn_socket.3compat.adoc
vendored
Normal file
|
@ -0,0 +1,78 @@
|
|||
= nn_socket(3compat)
|
||||
//
|
||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
|
||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||||
//
|
||||
// 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
|
||||
|
||||
nn_socket - create socket (compatible API)
|
||||
|
||||
== SYNOPSIS
|
||||
|
||||
[source,c]
|
||||
----
|
||||
#include <nanomsg/nn.h>
|
||||
|
||||
int nn_socket(int af, int proto);
|
||||
----
|
||||
|
||||
== DESCRIPTION
|
||||
|
||||
The `nn_socket()` function creates socket using the address family _af_ and
|
||||
protocol _proto_ and returns it.
|
||||
|
||||
NOTE: This function is provided for API
|
||||
xref:nng_compat.3compat.adoc[compatibility] with legacy _libnanomsg_.
|
||||
Consider using the relevant xref:libnng.3.adoc[modern API] instead.
|
||||
|
||||
IMPORTANT: Mixing the compatibility API and the modern API is not supported
|
||||
on a given socket.
|
||||
|
||||
NOTE: Some protocols, transports, and features are only available in the modern API.
|
||||
|
||||
The address family _af_ can be one of two values:
|
||||
|
||||
[horizontal]
|
||||
`AF_SP`:: Normal socket.
|
||||
`AF_SP_RAW`:: xref:nng.7.adoc#raw_mode[Raw mode] socket.
|
||||
|
||||
The protocol indicates the protocol to be used when creating the socket.
|
||||
The following protocols are defined:
|
||||
|
||||
[horizontal]
|
||||
`NN_PAIR`:: xref:nng_pair.7.adoc[Pair] protocol.
|
||||
`NN_PUB`:: xref:nng_pub.7.adoc[Publisher] protocol.
|
||||
`NN_SUB`:: xref:nng_sub.7.adoc[Subscriber] protocol.
|
||||
`NN_REQ`:: xref:nng_req.7.adoc[Requestor] protocol.
|
||||
`NN_REP`:: xref:nng_rep.7.adoc[Replier] protocol.
|
||||
`NN_PUSH`:: xref:nng_push.7.adoc[Push] protocol.
|
||||
`NN_PULL`:: xref:nng_pull.7.adoc[Pull] protocol.
|
||||
`NN_SURVEYOR`:: xref:nng_surveyor.7.adoc[Surveyor] protocol.
|
||||
`NN_RESPONDENT`:: xref:nng_respondent.7.adoc[Respondent] protocol.
|
||||
`NN_BUS`:: xref:nng_bus.7.adoc[Bus] protocol.
|
||||
|
||||
== RETURN VALUES
|
||||
|
||||
This function returns a valid socket number on success, and -1 on failure.
|
||||
|
||||
== ERRORS
|
||||
|
||||
[horizontal]
|
||||
`ENOMEM`:: Insufficient memory is available.
|
||||
`ENOTSUP`:: The protocol is not supported.
|
||||
`ETERM`:: The library is shutting down.
|
||||
|
||||
== SEE ALSO
|
||||
|
||||
[.text-left]
|
||||
xref:nng_socket.5.adoc[nng_socket(5)],
|
||||
xref:nn_close.3compat.adoc[nn_close(3compat)],
|
||||
xref:nn_errno.3compat.adoc[nn_errno(3compat)],
|
||||
xref:nng_compat.3compat.adoc[nng_compat(3compat)],
|
||||
xref:nng.7.adoc[nng(7)]
|
47
external/nng/docs/man/nn_strerror.3compat.adoc
vendored
Normal file
47
external/nng/docs/man/nn_strerror.3compat.adoc
vendored
Normal file
|
@ -0,0 +1,47 @@
|
|||
= nn_strerror(3compat)
|
||||
//
|
||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
|
||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||||
//
|
||||
// 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
|
||||
|
||||
nn_strerror - return message for error (compatible API)
|
||||
|
||||
== SYNOPSIS
|
||||
|
||||
[source,c]
|
||||
----
|
||||
#include <nanomsg/nn.h>
|
||||
|
||||
const char *nn_strerror(int err);
|
||||
----
|
||||
|
||||
== DESCRIPTION
|
||||
|
||||
The `nn_strerror()` function returns a human readable message corresponding
|
||||
to the given error number _err_.
|
||||
|
||||
NOTE: This function is provided for API
|
||||
xref:nng_compat.3compat.adoc[compatibility] with legacy _libnanomsg_.
|
||||
Consider using the relevant xref:libnng.3.adoc[modern API] instead.
|
||||
|
||||
== RETURN VALUES
|
||||
|
||||
This function returns the message corresponding to _err_.
|
||||
|
||||
== ERRORS
|
||||
|
||||
None.
|
||||
|
||||
== SEE ALSO
|
||||
|
||||
[.text-left]
|
||||
xref:nn_errno.3compat.adoc[nn_errno(3compat)],
|
||||
xref:nng_compat.3compat.adoc[nng_compat(3compat)],
|
||||
xref:nng.7.adoc[nng(7)]
|
59
external/nng/docs/man/nn_term.3compat.adoc
vendored
Normal file
59
external/nng/docs/man/nn_term.3compat.adoc
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
= nn_term(3compat)
|
||||
//
|
||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
|
||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||||
//
|
||||
// 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
|
||||
|
||||
nn_term - terminate library (compatible API)
|
||||
|
||||
== SYNOPSIS
|
||||
|
||||
[source,c]
|
||||
----
|
||||
#include <nanomsg/nn.h>
|
||||
|
||||
void nn_term(void);
|
||||
----
|
||||
|
||||
== DESCRIPTION
|
||||
|
||||
The `nn_term()` function closes any open sockets, and frees all resources
|
||||
allocated by the library.
|
||||
Any operations that are currently in progress will be terminated, and will
|
||||
fail with error `EBADF` or `ETERM`.
|
||||
|
||||
NOTE: This function is provided for API
|
||||
xref:nng_compat.3compat.adoc[compatibility] with legacy _libnanomsg_.
|
||||
Consider using the relevant xref:libnng.3.adoc[modern API] instead.
|
||||
|
||||
IMPORTANT: This function is not thread-safe, and is not suitable for use
|
||||
in library calls.
|
||||
The intended purpose of this is to clean up at application termination; for
|
||||
example by registering this function with `atexit()`.
|
||||
This can help prevent false leak reports caused when memory checkers notice
|
||||
global resources allocated by the library.
|
||||
Libraries should never use this function, but should explicitly close their
|
||||
own sockets directly.
|
||||
|
||||
== RETURN VALUES
|
||||
|
||||
None.
|
||||
|
||||
== ERRORS
|
||||
|
||||
None.
|
||||
|
||||
== SEE ALSO
|
||||
|
||||
[.text-left]
|
||||
xref:nn_errno.3compat.adoc[nn_errno(3compat)],
|
||||
xref:nn_socket.3compat.adoc[nn_socket(3compat)],
|
||||
xref:nng_compat.3compat.adoc[nng_compat(3compat)],
|
||||
xref:nng.7.adoc[nng(7)]
|
194
external/nng/docs/man/nng.7.adoc
vendored
Normal file
194
external/nng/docs/man/nng.7.adoc
vendored
Normal file
|
@ -0,0 +1,194 @@
|
|||
= nng(7)
|
||||
//
|
||||
// Copyright 2019 Staysail Systems, Inc. <info@staysail.tech>
|
||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||||
//
|
||||
// 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 - nanomsg next generation
|
||||
|
||||
== SYNOPSIS
|
||||
|
||||
*cc* ['flags'] 'files' *-lnng* ['libraries']
|
||||
|
||||
== DESCRIPTION
|
||||
|
||||
_NNG_ provides a common messaging framework intended to
|
||||
solve common communication problems in distributed applications.
|
||||
It offers a number of _protocols_, and also a number of _transports_.
|
||||
|
||||
The _protocols_ implement the semantics associated with particular
|
||||
communications scenarios, such as RPC style services, service discovery,
|
||||
publish/subscribe, and so forth.
|
||||
|
||||
The _transports_ provide support for underlying transport methods, such
|
||||
as TCP, IPC, websockets, and so forth.
|
||||
|
||||
_NNG_ is designed to permit easy creation of new _transports_ and,
|
||||
to a lesser extent, new _protocols_.
|
||||
|
||||
_NNG_ is wire compatible with the SP protocols described in
|
||||
the nanomsg project; projects using
|
||||
https://github.com/nanomsg/nanomsg[_libnanomsg_] can inter-operate with
|
||||
nng as well as other conforming implementations. (One such implementation
|
||||
is https://github.com/go-mangos/mangos[_mangos_].)
|
||||
Applications using _NNG_
|
||||
which wish to communicate with other libraries must ensure that they only
|
||||
use protocols or transports offered by the other library.
|
||||
|
||||
_NNG_ also offers a compatible API, permitting legacy code to
|
||||
be recompiled or relinked against _NNG_. When doing this, support for
|
||||
certain enhancements or features will likely be absent, requiring the
|
||||
application developer to use the new-style API.
|
||||
|
||||
_NNG_ is implemented in pure C; if you need bindings for
|
||||
other languages please check the http://nanomsg.org/[website].
|
||||
|
||||
=== Protocols
|
||||
|
||||
[horizontal]
|
||||
xref:nng_bus.7.adoc[nng_bus(7)]:: Bus protocol
|
||||
xref:nng_pair.7.adoc[nng_pair(7)]:: Pair protocol
|
||||
xref:nng_pub.7.adoc[nng_pub(7)]:: Publisher side of publish/subscribe protocol
|
||||
xref:nng_pull.7.adoc[nng_pull(7)]:: Pull side of pipeline protocol
|
||||
xref:nng_push.7.adoc[nng_push(7)]:: Push side of pipeline protocol
|
||||
xref:nng_sub.7.adoc[nng_sub(7)]:: Subscriber side of publish/subscribe protocol
|
||||
xref:nng_rep.7.adoc[nng_rep(7)]:: Reply side of request/reply protocol
|
||||
xref:nng_req.7.adoc[nng_req(7)]:: Request side of request/reply protocol
|
||||
xref:nng_respondent.7.adoc[nng_respondent(7)]:: Respondent side of survey protocol
|
||||
xref:nng_surveyor.7.adoc[nng_surveyor(7)]:: Surveyor side of survey protocol
|
||||
|
||||
=== Transports
|
||||
|
||||
[horizontal]
|
||||
xref:nng_inproc.7.adoc[nng_inproc(7)]:: Intra-process transport
|
||||
xref:nng_ipc.7.adoc[nng_ipc(7)]:: Inter-process transport
|
||||
xref:nng_tls.7.adoc[nng_tls(7)]:: TLSv1.2 over TCP transport
|
||||
xref:nng_tcp.7.adoc[nng_tcp(7)]:: TCP (and TCPv6) transport
|
||||
xref:nng_ws.7.adoc[nng_ws(7)]:: WebSocket transport
|
||||
xref:nng_zerotier.7.adoc[nng_zerotier(7)]:: ZeroTier transport
|
||||
|
||||
=== Conceptual Overview
|
||||
|
||||
_NNG_ presents a _socket_ view of networking.
|
||||
The sockets are constructed using protocol-specific functions, as a given
|
||||
socket implements precisely one protocol.
|
||||
|
||||
Each socket can be used to send and receive messages (if the protocol)
|
||||
supports it, and implements the appropriate protocol semantics.
|
||||
For example, xref:nng_sub.7.adoc[_sub_] sockets automatically filter incoming
|
||||
messages to discard those for topics that have not been subscribed.
|
||||
|
||||
_NNG_ sockets are message oriented, so that messages are either delivered
|
||||
wholly, or not at all. Partial delivery is not possible.
|
||||
Furthermore, _NNG_ does not provide any other delivery or ordering guarantees;
|
||||
messages may be dropped or reordered
|
||||
(Some protocols, such as xref:nng_req.7.adoc[_req_] may offer stronger
|
||||
guarantees by performing their own retry and validation schemes.)
|
||||
|
||||
Each socket can have zero, one, or many endpoints, which are either
|
||||
_listeners_ or _dialers_.
|
||||
(A given socket may freely choose whether it uses listeners, dialers, or both.)
|
||||
These endpoints provide access to underlying transports, such as TCP, etc.
|
||||
|
||||
Each endpoint is associated with a URL, which is a service address.
|
||||
For dialers, this will be the service address that will be contacted, whereas
|
||||
for listeners this is where the listener will accept new connections.
|
||||
|
||||
Endpoints do not themselves transport data.
|
||||
They are instead responsible for the creation of _pipes_, which can be
|
||||
thought of as message-oriented connected streams.
|
||||
Pipes frequently correspond to a single underlying byte stream.
|
||||
For example both IPC and TCP transports implement their
|
||||
pipes using a 1:1 relationship with a connected operating system socket.
|
||||
|
||||
Endpoints create pipes as needed.
|
||||
Listeners will create them when a new client connection request arrives,
|
||||
and dialers will generally create one, then wait for it to disconnect before
|
||||
reconnecting.
|
||||
|
||||
Most applications should not have to worry about endpoints or pipes at
|
||||
all; the socket abstraction should provide all the functionality needed
|
||||
other than in a few specific circumstances.
|
||||
|
||||
[[raw_mode]]
|
||||
==== Raw Mode
|
||||
|
||||
(((cooked mode)))(((raw mode)))
|
||||
Most applications will use sockets in normal, or _cooked_, mode.
|
||||
This mode provides the full semantics of the protocol.
|
||||
For example, xref:nng_req.7.adoc[_req_] sockets will automatically
|
||||
match a reply to a request, and resend requests periodically if no reply
|
||||
was received.
|
||||
|
||||
There are situations, such as with xref:nng_device.3.adoc[proxies],
|
||||
where it is desirable to bypass these semantics and simply pass messages
|
||||
to and from the socket with no extra semantic handling.
|
||||
This is possible using _raw_ mode sockets.
|
||||
|
||||
Raw mode sockets are generally constructed with a different function,
|
||||
such as xref:nng_req_open.3.adoc[`nng_req0_open_raw()`].
|
||||
Using these sockets, the application can simply send and receive messages,
|
||||
and is responsible for supplying any additional socket semantics.
|
||||
Typically this means that the application will need to inspect message
|
||||
headers on incoming messages, and supply them on outgoing messages.
|
||||
|
||||
TIP: The xref:nng_device.3.adoc[`nng_device()`] function only works with raw mode
|
||||
sockets, but as it only forwards the messages, no additional application
|
||||
processing is needed.
|
||||
|
||||
==== URLs
|
||||
|
||||
(((URL)))
|
||||
_NNG_ uses ((universal resource locators)) (URLs)
|
||||
following the format specified in
|
||||
https://tools.ietf.org/html/rfc3986[RFC 3986],
|
||||
including some schemes that are unique
|
||||
to SP.
|
||||
(((URL, canonicalized)))
|
||||
The URLs used in _NNG_ are canonicalized as follows, mostly in
|
||||
accordance with
|
||||
https://tools.ietf.org/html/rfc3986#section-6.2.2[RFC 3986 6.2.2]:
|
||||
|
||||
. The URL is parsed into scheme, userinfo, host, port, path, query and
|
||||
fragment components. (Not all of these members are necessarily present.)
|
||||
. The scheme, hostname, and port if present, are converted to lower case.
|
||||
. Percent-encoded values for
|
||||
https://tools.ietf.org/html/rfc3986#section-2.3[unreserved characters]
|
||||
converted to their unencoded forms.
|
||||
. Additionally URL percent-encoded values for characters in the path
|
||||
and with numeric values larger than 127 (i.e. not ASCII) are decoded.
|
||||
. The resulting path is checked for invalid UTF-8 sequences, consisting
|
||||
of surrogate pairs, illegal byte sequences, or overlong encodings.
|
||||
If this check fails, then the entire URL is considered invalid.
|
||||
. Path segments consisting of `.` and `..` are resolved as per
|
||||
https://tools.ietf.org/html/rfc3986#section-6.2.2.3[RFC 3986 6.2.2.3].
|
||||
. Further, empty path segments are removed, meaning that duplicate
|
||||
slash (`/`) separators are removed from the path.
|
||||
|
||||
Note that steps 4, 5, and 7 are not specified by RFC 3986, but performing
|
||||
them is believed to improve both the usability and security of
|
||||
applications, without violating RFC 3986 itself.
|
||||
|
||||
TIP: Port numbers may be service names in some instances, but it is recommended
|
||||
that numeric port numbers be used when known.
|
||||
If service names are used, it is recommended that they follow the naming
|
||||
conventions for C identifiers, and not be longer than 32 characters in length.
|
||||
This will maximize compatibility across systems and minimize opportunities for
|
||||
confusion when they are parsed on different systems.
|
||||
|
||||
=== API
|
||||
|
||||
The library API is documented at xref:libnng.3.adoc[libnng(3)].
|
||||
|
||||
== SEE ALSO
|
||||
|
||||
[.text-left]
|
||||
xref:libnng.3.adoc[libnng(3)],
|
||||
xref:nng_compat.3compat.adoc[nng_compat(3compat)]
|
70
external/nng/docs/man/nng_aio.5.adoc
vendored
Normal file
70
external/nng/docs/man/nng_aio.5.adoc
vendored
Normal file
|
@ -0,0 +1,70 @@
|
|||
= nng_aio(5)
|
||||
//
|
||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
|
||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||||
//
|
||||
// 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_aio - asynchronous I/O handle
|
||||
|
||||
== SYNOPSIS
|
||||
|
||||
[source, c]
|
||||
----
|
||||
#include <nng/nng.h>
|
||||
|
||||
typedef struct nng_aio nng_aio;
|
||||
----
|
||||
|
||||
== DESCRIPTION
|
||||
|
||||
An `nng_aio`(((aio))) is an opaque structure used in conjunction with
|
||||
((asynchronous I/O)) operations.
|
||||
Every asynchronous operation uses one of these structures, each of which
|
||||
can only be used with a single operation at a time.
|
||||
|
||||
Asynchronous operations are performed without blocking calling application
|
||||
threads.
|
||||
Instead the application registers a callback function to be executed
|
||||
when the operation is complete (whether successfully or not).
|
||||
This callback will be executed exactly once.
|
||||
|
||||
The asynchronous I/O framework also supports cancellation of
|
||||
operations that are already in progress
|
||||
(see xref:nng_aio_cancel.3.adoc[`nng_aio_cancel()`]), as well setting a maximum
|
||||
timeout for them to complete within
|
||||
(see xref:nng_aio_set_timeout.3.adoc[`nng_aio_set_timeout()`]).
|
||||
|
||||
It is also possible to initiate an asynchronous operation, and wait for it to
|
||||
complete using xref:nng_aio_wait.3.adoc[`nng_aio_wait()`].
|
||||
|
||||
These structures are created using the xref:nng_aio_alloc.3.adoc[`nng_aio_alloc()`],
|
||||
and destroyed using xref:nng_aio_free.3.adoc[`nng_aio_free()`].
|
||||
|
||||
== SEE ALSO
|
||||
|
||||
[.text-left]
|
||||
xref:nng_aio_abort.3.adoc[nng_aio_abort(3)],
|
||||
xref:nng_aio_alloc.3.adoc[nng_aio_alloc(3)],
|
||||
xref:nng_aio_cancel.3.adoc[nng_aio_cancel(3)],
|
||||
xref:nng_aio_count.3.adoc[nng_aio_count(3)],
|
||||
xref:nng_aio_free.3.adoc[nng_aio_free(3)],
|
||||
xref:nng_aio_get_input.3.adoc[nng_aio_get_input(3)],
|
||||
xref:nng_aio_get_msg.3.adoc[nng_aio_get_msg(3)],
|
||||
xref:nng_aio_get_output.3.adoc[nng_aio_get_output(3)],
|
||||
xref:nng_aio_result.3.adoc[nng_aio_result(3)],
|
||||
xref:nng_aio_set_input.3.adoc[nng_aio_set_input(3)],
|
||||
xref:nng_aio_set_iov.3.adoc[nng_aio_set_iov(3)],
|
||||
xref:nng_aio_set_msg.3.adoc[nng_aio_set_msg(3)],
|
||||
xref:nng_aio_set_timeout.3.adoc[nng_aio_set_timeout(3)],
|
||||
xref:nng_aio_stop.3.adoc[nng_aio_stop(3)],
|
||||
xref:nng_aio_wait.3.adoc[nng_aio_wait(3)],
|
||||
xref:nng_strerror.3.adoc[nng_strerror(3)],
|
||||
xref:nng_aio.5.adoc[nng_aio(5)],
|
||||
xref:nng.7.adoc[nng(7)]
|
55
external/nng/docs/man/nng_aio_abort.3.adoc
vendored
Normal file
55
external/nng/docs/man/nng_aio_abort.3.adoc
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
= nng_aio_abort(3)
|
||||
//
|
||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
|
||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||||
//
|
||||
// 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_aio_abort - abort asynchronous I/O operation
|
||||
|
||||
== SYNOPSIS
|
||||
|
||||
[source, c]
|
||||
----
|
||||
#include <nng/nng.h>
|
||||
|
||||
void nng_aio_abort(nng_aio *aio, int err);
|
||||
----
|
||||
|
||||
== DESCRIPTION
|
||||
|
||||
The `nng_aio_abort()` function aborts an operation previously started
|
||||
with the handle _aio_.
|
||||
If the operation is aborted, then the callback
|
||||
for the handle will be called, and the function
|
||||
xref:nng_aio_result.3.adoc[`nng_aio_result()`] will return the error _err_.
|
||||
|
||||
This function does not wait for the operation to be fully aborted, but
|
||||
returns immediately.
|
||||
|
||||
If no operation is currently in progress (either because it has already
|
||||
finished, or no operation has been started yet), then this function
|
||||
has no effect.
|
||||
|
||||
== RETURN VALUES
|
||||
|
||||
None.
|
||||
|
||||
== ERRORS
|
||||
|
||||
None.
|
||||
|
||||
== SEE ALSO
|
||||
|
||||
[.text-left]
|
||||
xref:nng_aio_alloc.3.adoc[nng_aio_alloc(3)],
|
||||
xref:nng_aio_cancel.3.adoc[nng_aio_cancel(3)],
|
||||
xref:nng_aio_result.3.adoc[nng_aio_result(3)],
|
||||
xref:nng_aio.5.adoc[nng_aio(5)],
|
||||
xref:nng.7.adoc[nng(7)]
|
88
external/nng/docs/man/nng_aio_alloc.3.adoc
vendored
Normal file
88
external/nng/docs/man/nng_aio_alloc.3.adoc
vendored
Normal file
|
@ -0,0 +1,88 @@
|
|||
= nng_aio_alloc(3)
|
||||
//
|
||||
// Copyright 2021 Staysail Systems, Inc. <info@staysail.tech>
|
||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||||
//
|
||||
// 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_aio_alloc - allocate asynchronous I/O handle
|
||||
|
||||
== SYNOPSIS
|
||||
|
||||
[source, c]
|
||||
----
|
||||
#include <nng/nng.h>
|
||||
|
||||
int nng_aio_alloc(nng_aio **aiop, void (*callb)(void *), void *arg);
|
||||
----
|
||||
|
||||
== DESCRIPTION
|
||||
|
||||
The `nng_aio_alloc()` function allocates a handle for ((asynchronous I/O))
|
||||
operations, and stores a pointer to it in __aiop__.
|
||||
The handle is initialized with a completion ((callback)) of _callb_,
|
||||
which will be executed when an associated asynchronous operation finishes.
|
||||
It will be called with the argument _arg_.
|
||||
|
||||
NOTE: The callback _callb_ must not perform any blocking operations, and
|
||||
must complete its execution quickly. If _callb_ does block, this can
|
||||
lead ultimately to an apparent "hang" or deadlock in the application.
|
||||
This also means you should avoid operations such as allocating new objects,
|
||||
which also means opening or closing sockets, dialers, and so forth.
|
||||
|
||||
TIP: If more complex or blocking work needs to be performed by _callb_, a separate
|
||||
thread can be used, along with a xref:nng_cv_alloc.3.adoc[condition variable]
|
||||
which can be signaled by the callback.
|
||||
|
||||
Asynchronous I/O operations all take an xref:nng_aio.5.adoc[`nng_aio`]
|
||||
handle such as allocated by this function.
|
||||
Such operations are usually started by a function that returns immediately.
|
||||
The operation is then run asynchronously, and completes sometime later.
|
||||
When that operation is complete, the callback supplied here is called,
|
||||
and that callback is able to determine the result of the operation using
|
||||
xref:nng_aio_result.3.adoc[`nng_aio_result()`],
|
||||
xref:nng_aio_count.3.adoc[`nng_aio_count()`],
|
||||
and xref:nng_aio_get_output.3.adoc[`nng_aio_get_output()`].
|
||||
|
||||
It is possible to wait synchronously for an otherwise asynchronous operation
|
||||
by using the function xref:nng_aio_wait.3.adoc[`nng_aio_wait()`].
|
||||
In that case, it is permissible for _callb_ and _arg_ to both be `NULL`.
|
||||
Note that if these are `NULL`, then it will not be possible to determine when the
|
||||
operation is complete except by calling the aforementioned
|
||||
xref:nng_aio_wait.3.adoc[`nng_aio_wait()`].
|
||||
|
||||
== RETURN VALUES
|
||||
|
||||
This function returns 0 on success, and non-zero otherwise.
|
||||
|
||||
== ERRORS
|
||||
|
||||
[horizontal]
|
||||
`NNG_ENOMEM`:: Insufficient free memory to perform the operation.
|
||||
|
||||
== SEE ALSO
|
||||
|
||||
[.text-left]
|
||||
xref:nng_aio_abort.3.adoc[nng_aio_abort(3)],
|
||||
xref:nng_aio_cancel.3.adoc[nng_aio_cancel(3)],
|
||||
xref:nng_aio_count.3.adoc[nng_aio_count(3)],
|
||||
xref:nng_aio_free.3.adoc[nng_aio_free(3)],
|
||||
xref:nng_aio_get_input.3.adoc[nng_aio_get_input(3)],
|
||||
xref:nng_aio_get_msg.3.adoc[nng_aio_get_msg(3)],
|
||||
xref:nng_aio_get_output.3.adoc[nng_aio_get_output(3)],
|
||||
xref:nng_aio_result.3.adoc[nng_aio_result(3)],
|
||||
xref:nng_aio_set_input.3.adoc[nng_aio_set_input(3)],
|
||||
xref:nng_aio_set_iov.3.adoc[nng_aio_set_iov(3)],
|
||||
xref:nng_aio_set_msg.3.adoc[nng_aio_set_msg(3)],
|
||||
xref:nng_aio_set_timeout.3.adoc[nng_aio_set_timeout(3)],
|
||||
xref:nng_aio_stop.3.adoc[nng_aio_stop(3)],
|
||||
xref:nng_aio_wait.3.adoc[nng_aio_wait(3)],
|
||||
xref:nng_strerror.3.adoc[nng_strerror(3)],
|
||||
xref:nng_aio.5.adoc[nng_aio(5)],
|
||||
xref:nng.7.adoc[nng(7)]
|
64
external/nng/docs/man/nng_aio_begin.3.adoc
vendored
Normal file
64
external/nng/docs/man/nng_aio_begin.3.adoc
vendored
Normal file
|
@ -0,0 +1,64 @@
|
|||
= nng_aio_begin(3)
|
||||
//
|
||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
|
||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||||
//
|
||||
// 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_aio_begin - begin asynchronous I/O operation
|
||||
|
||||
== SYNOPSIS
|
||||
|
||||
[source, c]
|
||||
----
|
||||
#include <nng/nng.h>
|
||||
|
||||
bool nng_aio_begin(nng_aio *aio);
|
||||
----
|
||||
|
||||
== DESCRIPTION
|
||||
|
||||
The `nng_aio_begin()` function is called by the I/O provider to indicate that
|
||||
it is going to process the operation.
|
||||
|
||||
The function may return `false`, indicating that the _aio_ has been closed
|
||||
by the caller asynchronously.
|
||||
In this case the provider should abandon the operation and do nothing else.
|
||||
|
||||
This operation should be called at the start of any I/O operation, and must
|
||||
be called not more than once for a given I/O operation on a given _aio_.
|
||||
|
||||
Once this function is called, if `true` is returned, then the provider MUST
|
||||
guarantee that xref:nng_aio_finish.3.adoc[`nng_aio_finish()`] is called for the _aio_
|
||||
exactly once, when the operation is complete or canceled.
|
||||
|
||||
NOTE: This function is only for I/O providers (those actually performing
|
||||
the operation such as HTTP handler functions or transport providers); ordinary
|
||||
users of the _aio_ should not call this function.
|
||||
|
||||
== RETURN VALUES
|
||||
|
||||
[horizontal]
|
||||
`true`:: The operation has been started.
|
||||
`false`:: The operation cannot be started.
|
||||
|
||||
== ERRORS
|
||||
|
||||
None.
|
||||
|
||||
== SEE ALSO
|
||||
|
||||
[.text-left]
|
||||
xref:nng_aio_alloc.3.adoc[nng_aio_alloc(3)],
|
||||
xref:nng_aio_cancel.3.adoc[nng_aio_cancel(3)],
|
||||
xref:nng_aio_defer.3.adoc[nng_aio_defer(3)],
|
||||
xref:nng_aio_finish.3.adoc[nng_aio_finish(3)],
|
||||
xref:nng_aio_result.3.adoc[nng_aio_result(3)],
|
||||
xref:nng_aio.5.adoc[nng_aio(5)],
|
||||
xref:nng.7.adoc[nng(7)]
|
58
external/nng/docs/man/nng_aio_cancel.3.adoc
vendored
Normal file
58
external/nng/docs/man/nng_aio_cancel.3.adoc
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
= nng_aio_cancel(3)
|
||||
//
|
||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
|
||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||||
//
|
||||
// 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_aio_cancel - cancel asynchronous I/O operation
|
||||
|
||||
== SYNOPSIS
|
||||
|
||||
[source, c]
|
||||
----
|
||||
#include <nng/nng.h>
|
||||
|
||||
void nng_aio_cancel(nng_aio *aio);
|
||||
----
|
||||
|
||||
== DESCRIPTION
|
||||
|
||||
The `nng_aio_cancel()` function aborts an operation previously started
|
||||
with the handle _aio_.
|
||||
If the operation is aborted, then the callback
|
||||
for the handle will be called, and the function
|
||||
xref:nng_aio_result.3.adoc[`nng_aio_result()`] will return the error `NNG_ECANCELED`.
|
||||
|
||||
This function does not wait for the operation to be fully aborted, but
|
||||
returns immediately.
|
||||
|
||||
If no operation is currently in progress (either because it has already
|
||||
finished, or no operation has been started yet), then this function
|
||||
has no effect.
|
||||
|
||||
NOTE: This function is the same as calling
|
||||
xref:nng_aio_abort.3.adoc[`nng_aio_abort()`] with the error `NNG_ECANCELED`.
|
||||
|
||||
== RETURN VALUES
|
||||
|
||||
None.
|
||||
|
||||
== ERRORS
|
||||
|
||||
None.
|
||||
|
||||
== SEE ALSO
|
||||
|
||||
[.text-left]
|
||||
xref:nng_aio_abort.3.adoc[nng_aio_abort(3)],
|
||||
xref:nng_aio_alloc.3.adoc[nng_aio_alloc(3)],
|
||||
xref:nng_aio_result.3.adoc[nng_aio_result(3)],
|
||||
xref:nng_aio.5.adoc[nng_aio(5)],
|
||||
xref:nng.7.adoc[nng(7)]
|
61
external/nng/docs/man/nng_aio_count.3.adoc
vendored
Normal file
61
external/nng/docs/man/nng_aio_count.3.adoc
vendored
Normal file
|
@ -0,0 +1,61 @@
|
|||
= nng_aio_count(3)
|
||||
//
|
||||
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
|
||||
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
||||
//
|
||||
// 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_aio_count - return number of bytes transferred
|
||||
|
||||
== SYNOPSIS
|
||||
|
||||
[source, c]
|
||||
----
|
||||
#include <nng/nng.h>
|
||||
|
||||
size_t nng_aio_count(nng_aio *aio);
|
||||
----
|
||||
|
||||
== DESCRIPTION
|
||||
|
||||
The `nng_aio_count()` returns the number of bytes transferred by the
|
||||
asynchronous operation associated with the handle _aio_.
|
||||
|
||||
Some asynchronous operations do not provide meaningful data for this
|
||||
function; for example operations that establish connections do not
|
||||
transfer user data (they may transfer protocol data though) -- in this case
|
||||
this function will generally return zero.
|
||||
|
||||
This function is most useful when used with operations that make use of
|
||||
of a scatter/gather vector (set by xref:nng_aio_set_iov.3.adoc[`nng_aio_set_iov()`]).
|
||||
|
||||
NOTE: The return value from this function is undefined if the operation
|
||||
has not completed yet.
|
||||
Either call this from the handle's completion callback,
|
||||
or after waiting for the operation to complete with
|
||||
xref:nng_aio_wait.3.adoc[`nng_aio_wait()`].
|
||||
|
||||
== RETURN VALUES
|
||||
|
||||
The number of bytes transferred by the operation.
|
||||
|
||||
== ERRORS
|
||||
|
||||
None.
|
||||
|
||||
== SEE ALSO
|
||||
|
||||
[.text-left]
|
||||
xref:nng_aio_alloc.3.adoc[nng_aio_alloc(3)],
|
||||
xref:nng_aio_result.3.adoc[nng_aio_result(3)],
|
||||
xref:nng_aio_set_iov.3.adoc[nng_aio_set_iov(3)],
|
||||
xref:nng_aio_wait.3.adoc[nng_aio_wait(3)],
|
||||
xref:nng_strerror.3.adoc[nng_strerror(3)],
|
||||
xref:nng_aio.5.adoc[nng_aio(5)],
|
||||
xref:nng.7.adoc[nng(7)]
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue