git subtree add --squash -P external/nng https://github.com/nanomsg/nng.git v1.8.0
Merge commit '7063e2102e655079574d6644b323f28f48685c5a' as 'external/nng'
This commit is contained in:
commit
b3f1d5611f
774 changed files with 131758 additions and 0 deletions
16
external/nng/.clang-format
vendored
Normal file
16
external/nng/.clang-format
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
BasedOnStyle: WebKit
|
||||
UseTab: ForIndentation
|
||||
IndentWidth: 8
|
||||
ColumnLimit: 79
|
||||
AlignConsecutiveAssignments: true
|
||||
AlignConsecutiveDeclarations: true
|
||||
AlignTrailingComments: true
|
||||
AlignEscapedNewlines: Left
|
||||
PointerAlignment: Right
|
||||
DerivePointerAlignment: false
|
||||
ForEachMacros: ['NNI_LIST_FOREACH']
|
||||
AlwaysBreakAfterReturnType: TopLevelDefinitions
|
||||
SpaceAfterCStyleCast: true
|
||||
AllowShortFunctionsOnASingleLine: Inline
|
||||
BreakBeforeBinaryOperators: None
|
||||
TabWidth: 8
|
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
|
24
external/nng/.github/workflows/darwin.yml
vendored
Normal file
24
external/nng/.github/workflows/darwin.yml
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
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 Mbed TLS
|
||||
run: brew install mbedtls
|
||||
|
||||
- name: Install ninja
|
||||
run: brew install ninja
|
||||
|
||||
- name: Configure
|
||||
run: mkdir build && cd build && cmake -G Ninja -DNNG_ENABLE_TLS=ON ..
|
||||
|
||||
- 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
|
36
external/nng/.github/workflows/sanitizer.yml
vendored
Normal file
36
external/nng/.github/workflows/sanitizer.yml
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
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
|
||||
|
||||
- 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 -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
|
29
external/nng/.github/workflows/windows.yml
vendored
Normal file
29
external/nng/.github/workflows/windows.yml
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
name: windows
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
build:
|
||||
name: build
|
||||
runs-on: [windows-latest]
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v1
|
||||
|
||||
- name: vcpkg build
|
||||
id: vcpkg
|
||||
uses: johnwason/vcpkg-action@v6
|
||||
with:
|
||||
pkgs: mbedtls
|
||||
triplet: x64-windows
|
||||
token: ${{ github.token }}
|
||||
github-binarycache: true
|
||||
|
||||
- name: Configure
|
||||
run: cmake ${{ steps.vcpkg.outputs.vcpkg-cmake-config }} -D NNG_ENABLE_TLS=ON -B build
|
||||
|
||||
- name: Build
|
||||
run: cmake --build build
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
cd build
|
||||
ctest -C Debug --output-on-failure
|
13
external/nng/.gitignore
vendored
Normal file
13
external/nng/.gitignore
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
build
|
||||
lxbuild
|
||||
winbuild
|
||||
wbuild
|
||||
.cache
|
||||
.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
|
312
external/nng/CMakeLists.txt
vendored
Normal file
312
external/nng/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,312 @@
|
|||
#
|
||||
# Copyright 2024 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()
|
||||
if (NNG_ENABLE_COMPAT)
|
||||
target_compile_definitions(nng PRIVATE NNG_ENABLE_COMPAT)
|
||||
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)
|
||||
|
||||
# IPv6 enable
|
||||
nng_defines_if(NNG_ENABLE_IPV6 NNG_ENABLE_IPV6)
|
||||
|
||||
set(NNG_RESOLV_CONCURRENCY 4 CACHE STRING "Resolver (DNS) concurrency.")
|
||||
mark_as_advanced(NNG_RESOLV_CONCURRENCY)
|
||||
if (NNG_RESOLV_CONCURRENCY)
|
||||
add_definitions(-DNNG_RESOLV_CONCURRENCY=${NNG_RESOLV_CONCURRENCY})
|
||||
endif ()
|
||||
|
||||
set(NNG_NUM_TASKQ_THREADS 0 CACHE STRING "Fixed number of task threads, 0 for automatic")
|
||||
mark_as_advanced(NNG_NUM_TASKQ_THREADS)
|
||||
if (NNG_NUM_TASKQ_THREADS)
|
||||
add_definitions(-DNNG_NUM_TASKQ_THREADS=${NNG_NUM_TASKQ_THREADS})
|
||||
endif ()
|
||||
|
||||
set(NNG_MAX_TASKQ_THREADS 16 CACHE STRING "Upper bound on task 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 ()
|
||||
|
||||
# Expire threads. This runs the timeout handling, and having more of them
|
||||
# reduces contention on the common locks used for aio expiration.
|
||||
set(NNG_NUM_EXPIRE_THREADS 0 CACHE STRING "Fixed number of expire threads, 0 for automatic")
|
||||
mark_as_advanced(NNG_NUM_EXPIRE_THREADS)
|
||||
if (NNG_NUM_EXPIRE_THREADS)
|
||||
add_definitions(-DNNG_NUM_EXPIRE_THREADS=${NNG_NUM_EXPIRE_THREADS})
|
||||
endif ()
|
||||
|
||||
set(NNG_MAX_EXPIRE_THREADS 8 CACHE STRING "Upper bound on expire threads, 0 for no limit")
|
||||
mark_as_advanced(NNG_MAX_EXPIRE_THREADS)
|
||||
if (NNG_MAX_EXPIRE_THREADS)
|
||||
add_definitions(-DNNG_MAX_EXPIRE_THREADS=${NNG_MAX_EXPIRE_THREADS})
|
||||
endif()
|
||||
|
||||
# Poller threads. These threads run the pollers. This is mostly used
|
||||
# on Windows right now, as the POSIX platforms use a single threaded poller.
|
||||
set(NNG_NUM_POLLER_THREADS 0 CACHE STRING "Fixed number of I/O poller threads, 0 for automatic")
|
||||
if (NNG_NUM_POLLER_THREADS)
|
||||
add_definitions(-DNNG_NUM_POLLER_THREADS=${NNG_NUM_POLLER_THREADS})
|
||||
endif ()
|
||||
mark_as_advanced(NNG_NUM_POLLER_THREADS)
|
||||
|
||||
set(NNG_MAX_POLLER_THREADS 8 CACHE STRING "Upper bound on I/O poller threads, 0 for no limit")
|
||||
mark_as_advanced(NNG_MAX_POLLER_THREADS)
|
||||
if (NNG_MAX_POLLER_THREADS)
|
||||
add_definitions(-DNNG_MAX_POLLER_THREADS=${NNG_MAX_POLLER_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.
|
180
external/nng/README.adoc
vendored
Normal file
180
external/nng/README.adoc
vendored
Normal file
|
@ -0,0 +1,180 @@
|
|||
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 project page at https://github.com/nanomsg/nng.
|
||||
|
||||
image:https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/badges/StandWithUkraine.svg[Stand With Ukraine,link="https://stand-with-ukraine.pp.ua"]
|
||||
image:https://img.shields.io/github/actions/workflow/status/nanomsg/nng/linux.yml?branch=master&logoColor=grey&logo=ubuntu&label=[Linux Status,link="https://github.com/nanomsg/nng/actions"]
|
||||
image:https://img.shields.io/github/actions/workflow/status/nanomsg/nng/windows.yml?branch=master&logoColor=grey&logo=windows&label=[Windows Status,link="https://github.com/nanomsg/nng/actions"]
|
||||
image:https://img.shields.io/github/actions/workflow/status/nanomsg/nng/darwin.yml?branch=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/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"]
|
||||
|
||||
Please see <<UKRAINE#,here>> for an important message for the people of Russia.
|
||||
|
||||
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[Mbed TLS]. 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/nng.7.adoc#,nng(7)>> page provides a conceptual overview and links to
|
||||
manuals for various patterns.
|
||||
The <<docs/man/libnng.3.adoc#,libnng(3)>> page is a good starting point for the API reference.
|
||||
|
||||
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.].
|
115
external/nng/RELEASE_NOTES.adoc
vendored
Normal file
115
external/nng/RELEASE_NOTES.adoc
vendored
Normal file
|
@ -0,0 +1,115 @@
|
|||
ifdef::env-github[]
|
||||
:note-caption: :information_source:
|
||||
:important-caption: :heavy_exclamation_mark:
|
||||
endif::[]
|
||||
|
||||
= RELEASE NOTES FOR NNG v1.7.0
|
||||
|
||||
This document has the following sections:
|
||||
|
||||
* Notable Changes
|
||||
* End of Feature Announcements
|
||||
|
||||
== Notable Changes (since 1.6.0)
|
||||
|
||||
A new compile time setting, `NNG_MAX_POLLER_THREADS` is introduced,
|
||||
with a default value of 8, and will limit the number of threads
|
||||
used for pollers that are concurrent (currently only Windows).
|
||||
Additionally, for single core systems only two threads will be started
|
||||
instead of four.
|
||||
|
||||
A new supplemental API, nng_id_map(3), is made available.
|
||||
This exposes the internal ID hash API NNG uses mapping integer IDs
|
||||
(like socket IDs) to data structures.
|
||||
It also brings back support for 64-bit IDs.
|
||||
See bug #1740.
|
||||
|
||||
Setting the `NNG_OPT_RECVMAXSZ` setting no longer affects pipes
|
||||
that are already established. The old behavior was undocumented
|
||||
and racy. Please set this setting before starting any listeners
|
||||
or dialers.
|
||||
|
||||
A new transport (experimental), for `socket://` is available.
|
||||
This allows one to create a connection using sockets created
|
||||
with `socketpair()` (or the new `nng_socket_pair()` supplemental API),
|
||||
which can help use cases where file descriptors are passed between
|
||||
processes or inherited via `fork()`. This API is only available on
|
||||
Linux. It does have somewhat different semantics for establishing
|
||||
the connection, so please see the manual page for `nng_socket(5)` for more information.
|
||||
|
||||
WebSocket close is fixed to conform to RFC 6455, sending the
|
||||
close frame, and waiting to receive the close frame from the
|
||||
peer. This allows websocket based connections to ensure that
|
||||
data messages are fully delivered before shutting down.
|
||||
See bugs #1733, #1734 and #1735.
|
||||
Thanks @alawn-wang for the inspiration and a first
|
||||
draft of the change.
|
||||
|
||||
The REQ and SURVEYOR protocols were fixed to improve scalability
|
||||
when many clients or many contexts are used. As part of this change,
|
||||
a new option, `NNG_OPT_REQ_RESENDTICK` is available to adjust how
|
||||
often we check for expired requests.
|
||||
|
||||
A new ability to override compile-time settings for thread counts
|
||||
is available. This facility is considered experimental, and is not
|
||||
documented in manual pages -- and is subject to change without notice.
|
||||
Please see nng_init_set_parameter() in the nng.h header file. The
|
||||
values that can be tuned are listed there along with comments
|
||||
describing their use. See bug #1572.
|
||||
|
||||
As part of the fixes for #1572, tunable values for setting fixed
|
||||
values (rather upper limits) for thread counts are now exposed properly
|
||||
via CMake variables. These are `NNG_NUM_EXPIRE_THREADS` and `NNG_NUM_TASKQ_THREADS`.
|
||||
|
||||
A new API, `nng_aio_set_expire()` is introduced as a complement to
|
||||
`nng_aio_set_timeout()`. This provides absolute expiration times,
|
||||
which may be easier in circumstances involving multiple actions such
|
||||
as common state-machine based idioms.
|
||||
|
||||
A bug which caused TLS connections to spin on accept, causing high
|
||||
CPU usage, is fixed. (See bug #1673)
|
||||
Various minor documentation fixes were made, some contributed by
|
||||
Patrik Wenger <patrik.wenger@mindclue.ch>.
|
||||
|
||||
== End of Feature Announcements
|
||||
|
||||
=== Windows Legacy Support
|
||||
|
||||
As announced in 1.6.0,
|
||||
NNG no longer officially claims support for Windows Vista, Windows 7, Windows 8, or Windows 8.1.
|
||||
We have no ability to build or test these versions, and Microsoft no longer supports them.
|
||||
Continued use of these systems may be possible, but future changes may break
|
||||
compatibility with these systems without further notice.
|
||||
|
||||
=== Windows Named Pipe Support Changes
|
||||
|
||||
A future release of NNG may make the ipc:// URL format operate over UNIX domain sockets by default.
|
||||
We plan to do this for the other projects we control, such as mangos, as well.
|
||||
|
||||
Should this occur, it will be breaking for Windows versions older than Windows 10 17063.
|
||||
|
||||
=== macOS Legacy Support
|
||||
|
||||
As announced in 1.6.0,
|
||||
NNG no longer officially supports macOS versions older than 10.12.
|
||||
Future versions of NNG may depend on features not available on versions of macOS older than 10.12.
|
||||
|
||||
=== Documentation Restructuring
|
||||
|
||||
A future release of NNG may restructure the documentation to make it more
|
||||
approachable for more users. This would break the organization as UNIX manual
|
||||
pages, and would also drop the ability to format them as UNIX nroff source.
|
||||
The best way to view this documentation is on the NNG website, or with the PDF or printed manual.
|
||||
|
||||
=== ZeroTier Incompatible Changes
|
||||
|
||||
A future release of NNG may break compatibility for applications built using earlier versions
|
||||
of NNG when using the ZeroTier transport. ZeroTier support is an experimental feature.
|
||||
|
||||
=== Pair1 Polyamorous Mode
|
||||
|
||||
A future release of NNG may remove Pair 1 Polyamorous support, but *only* if a suitable
|
||||
replacement is provided. Pair1 Polyamorous mode is an experimental feature.
|
||||
|
||||
Alternatively we may change the Pair1 wire protocol in a way that breaks compatibility with
|
||||
earlier versions of Pair1 Polyamorous mode.
|
90
external/nng/UKRAINE.adoc
vendored
Normal file
90
external/nng/UKRAINE.adoc
vendored
Normal file
|
@ -0,0 +1,90 @@
|
|||
# Ukraine, Russia, and a World Tragedy
|
||||
|
||||
## A message to those inside Russia
|
||||
|
||||
### Written March 4, 2022.
|
||||
|
||||
It is with a very heavy heart that I write this. I am normally opposed to the use of open source
|
||||
projects to communicate political positions or advocate for things outside the immediate relevancy
|
||||
to that project.
|
||||
|
||||
However, the events occurring in Ukraine, and specifically the unprecedented invasion of Ukraine by
|
||||
Russian forces operating under orders from Russian President Vladimir Putin compel me to speak out.
|
||||
|
||||
Those who know me, know that I have family, friends, and colleagues in Russia, and Ukraine both. My closest friends
|
||||
have historically been Russian friends my wife's hometown of Chelyabinsk. I myself have in the past
|
||||
frequently traveled to Russia, and indeed operated a software development firm with offices in St. Petersburg.
|
||||
I had a special kinship with Russia and its people.
|
||||
|
||||
I say "had", because I fear that the actions of Putin, and the massive disinformation campaign that his regime
|
||||
has waged inside Russia, mean that it's likely that I won't see those friends again. At present, I'm not sure
|
||||
my wife will see her own mother again. We no longer feel it's safe for either of us to return Russia given
|
||||
actions taken by the regime to crack down on those who express disagreement.
|
||||
|
||||
Russian citizens are being led to believe it is acting purely defensively, and that only legitimate military
|
||||
targets are being targeted, and that all the information we have received in the West are fakes.
|
||||
|
||||
I am confident that nothing could be further from the truth.
|
||||
|
||||
This has caused many in Russia, including people whom I respect and believe to be smarter than this, to
|
||||
stand by Putin, and endorse his actions. The claim is that the entirety of NATO is operating at the behest
|
||||
of the USA, and that the entirety of Europe was poised to attack Russia. While this is clearly absurd to those
|
||||
of us with any understanding of western politics, Russian citizens are being fed this lie, and believing it.
|
||||
|
||||
If you're reading this from inside Russia -- YOU are the person that I hope this message reaches. Your
|
||||
government is LYING to you. Of course, all governments lie all the time. But consider this. Almost the
|
||||
entire world has condemned the invasion of Ukraine as criminal, and has applied sanctions. Even countries
|
||||
which have poor relations with the US sanctioning Russia, as well as nations which historically have remained
|
||||
neutral. (Famously neutral -- even during World War II, Switzerland has acted to apply sanctions in
|
||||
concert with the rest of the world.)
|
||||
|
||||
Ask yourself, why does Putin fear a free press so much, if what he says is true? Why the crack-downs on
|
||||
children expressing only a desire for peace with Ukraine? Why would the entire world unified against him,
|
||||
if Putin was in the right? Why would the only countries that stood with Russia against
|
||||
the UN resolution to condemn these acts as crimes be Belarus, North Korea, and Syria? Even countries normally
|
||||
allied to Russia could not bring themselves to do more than abstain from the vote to condemn it.
|
||||
|
||||
To be clear, I do not claim that the actions taken by the West or by the Ukrainian government were completely
|
||||
blameless. On the contrary, I understand that Western media is biased, and the truth is rarely exactly
|
||||
as reported. I believe that there is a kernel of truth in the claims of fascists and ultra-nationalist
|
||||
militias operating in Ukraine and specifically Donbas. However, I am also equally certain that Putin's
|
||||
response is out of proportion, and that concerns about such militias are principally just a pretext to justify
|
||||
an invasion.
|
||||
|
||||
Europe is at war, unlike we've seen in my lifetime. The world is more divided, and closer to nuclear holocaust
|
||||
than it has been since the Cold War. And that is 100% the fault of Putin.
|
||||
|
||||
While Putin remains in power, there cannot really be any way for Russian international relations to return
|
||||
to normal. Putin has set your country on a path to return to the Cold War, likely because he fancies himself
|
||||
to be a new Stalin. However, unlike the Soviet Union, the Russian economy does not have the wherewithal to
|
||||
stand on its own, and the invasion of Ukraine has fully ensured that Russia will not find any friends anywhere
|
||||
else in Europe, and probably few places in Asia.
|
||||
|
||||
The *only* paths forward for Russia are either a Russia without Putin (and those who would support his agenda),
|
||||
or a complete breakdown of Russian prosperity, likely followed by the increasing international conflict that will
|
||||
be the natural escalation from a country that is isolated and impoverished. Those of us observing from the West are
|
||||
gravely concerned, because we cannot see any end to this madness that does not result in nuclear conflict,
|
||||
unless from within.
|
||||
|
||||
In the meantime, the worst prices will be paid for by innocents in Ukraine, and by young Russian men
|
||||
forced to carry out the orders of Putin's corrupt regime.
|
||||
|
||||
And *that* is why I write this -- to appeal to those within Russia to open your eyes, and think with
|
||||
your minds. It is right and proper to be proud of your country and its rich heritage. But it is also
|
||||
right and proper to look for ways to save it from the ruinous path that its current leadership has set it upon,
|
||||
and to recognize when that leadership is no longer acting in interest of the country or its people.
|
||||
|
||||
- Garrett D'Amore, March 4, 2022
|
||||
|
||||
Updates on March 16, 2024:
|
||||
|
||||
I've made some minor typographical fixes.
|
||||
|
||||
It is extremely distressing to see that two years on, the
|
||||
people of both Ukraine and Russia continue to suffer under this needless, pointless, conflict fought solely to assuage
|
||||
the ego of a dictator.
|
||||
|
||||
The actions done here, have killed thousands, probably hundreds of thousands, of soldiers and civilians alike, and there seems to be no end to the madness. I still pray for sanity to return, because the current path, if followed
|
||||
to its logical conclusion, most likely ends in apocalpyse.
|
||||
|
||||
If you find my sharing these truths uncomfortable, please feel welcome to cease use of my software. While the license does permit use by anyone for any reason, I would not be displeased if the Russian military, and those sympathetic to it, declined from use of any of my work.
|
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 ()
|
119
external/nng/cmake/FindMbedTLS.cmake
vendored
Normal file
119
external/nng/cmake/FindMbedTLS.cmake
vendored
Normal file
|
@ -0,0 +1,119 @@
|
|||
#
|
||||
# Copyright 2024 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.
|
||||
# This tries to emulate the same expectations that the stock Mbed TLS
|
||||
# module uses in Mbed TLS v3.x.
|
||||
#
|
||||
# Sets the following:
|
||||
#
|
||||
# MbedTLS_FOUND - True if we found Mbed TLS.
|
||||
# MbedTLS_TARGET - Target of the mbedtls library.
|
||||
# MbedX509_TARGET - Target of the mbedx509 library.
|
||||
# MbedCrypto_TARGET - Target of the mbedcrypto library.
|
||||
# MbedTLS_VERSION - $major.$minor.$revision (e.g. ``2.6.0``).
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# Hints:
|
||||
#
|
||||
# Set ``MBEDTLS_ROOT`` to the root directory of Mbed TLS installation.
|
||||
#
|
||||
|
||||
set(_MBEDTLS_ROOT_HINTS ${MBEDTLS_ROOT} ENV MBEDTLS_ROOT)
|
||||
if (NOT _MBEDTLS_ROOT_HINTS)
|
||||
set(_MBEDTLS_ROOT_HINTS ${MBEDTLS_ROOT_DIR} ENV MBEDTLS_ROOT_DIR)
|
||||
endif()
|
||||
|
||||
set(_MBED_REQUIRED_VARS MbedTLS_TARGET MbedX509_TARGET MbedCrypto_TARGET MbedTLS_VERSION)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
include(CMakePushCheckState)
|
||||
|
||||
find_path(_MBEDTLS_INCLUDE_DIR
|
||||
NAMES mbedtls/ssl.h
|
||||
HINTS ${_MBEDTLS_ROOT_HINTS}
|
||||
# PATHS /usr/local
|
||||
PATH_SUFFIXES include)
|
||||
|
||||
find_library(_MBEDCRYPTO_LIBRARY
|
||||
NAMES mbedcrypto
|
||||
HINTS ${_MBEDTLS_ROOT_HINTS}
|
||||
# PATHS /usr/local
|
||||
# PATH_SUFFIXES lib
|
||||
)
|
||||
|
||||
find_library(_MBEDX509_LIBRARY
|
||||
NAMES mbedx509
|
||||
HINTS ${_MBEDTLS_ROOT_HINTS}
|
||||
#PATHS /usr/local
|
||||
# PATH_SUFFIXES lib
|
||||
)
|
||||
|
||||
find_library(_MBEDTLS_LIBRARY
|
||||
NAMES mbedtls
|
||||
HINTS ${_MBEDTLS_ROOT_HINTS}
|
||||
#PATHS /usr/local
|
||||
#PATH_SUFFIXES lib
|
||||
)
|
||||
|
||||
if ("${_MBEDTLS_TLS_LIBRARY}" STREQUAL "_MBEDTLS_TLS_LIBRARY-NOTFOUND")
|
||||
message("Failed to find Mbed TLS library")
|
||||
else()
|
||||
|
||||
cmake_push_check_state(RESET)
|
||||
set(CMAKE_REQUIRED_INCLUDES ${_MBEDTLS_INCLUDE_DIR} ${CMAKE_REQUIRED_INCLUDES_${BUILD_TYPE}})
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES ${_MBEDTLS_LIBRARY} ${_MBEDX509_LIBRARY} ${_MBEDCRYPTO_LIBRARY})
|
||||
check_symbol_exists(mbedtls_ssl_init "mbedtls/ssl.h" _MBEDTLS_V2_OR_NEWER)
|
||||
cmake_pop_check_state()
|
||||
|
||||
if (NOT _MBEDTLS_V2_OR_NEWER)
|
||||
message("Mbed TLS too old (must be version 2 or newer) ${_MBEDTLS_V2_OR_NEWER} UP ${_MbedTLS_V2}")
|
||||
|
||||
else()
|
||||
# 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})
|
||||
message("Mbed TLS version: ${MbedTLS_VERSION}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
add_library(MbedTLS::mbedtls UNKNOWN IMPORTED)
|
||||
add_library(MbedTLS::mbedx509 UNKNOWN IMPORTED)
|
||||
add_library(MbedTLS::mbedcrypto UNKNOWN IMPORTED)
|
||||
|
||||
|
||||
set_target_properties(MbedTLS::mbedtls PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${_MBEDTLS_INCLUDE_DIR}")
|
||||
set_target_properties(MbedTLS::mbedx509 PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${_MBEDTLS_INCLUDE_DIR}")
|
||||
set_target_properties(MbedTLS::mbedcrypto PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${_MBEDTLS_INCLUDE_DIR}")
|
||||
|
||||
set_target_properties(MbedTLS::mbedtls PROPERTIES IMPORTED_LOCATION "${_MBEDTLS_LIBRARY}")
|
||||
set_target_properties(MbedTLS::mbedx509 PROPERTIES IMPORTED_LOCATION "${_MBEDX509_LIBRARY}")
|
||||
set_target_properties(MbedTLS::mbedcrypto PROPERTIES IMPORTED_LOCATION "${_MBEDCRYPTO_LIBRARY}")
|
||||
|
||||
set(MbedTLS_TARGET MbedTLS::mbedtls)
|
||||
set(MbedX509_TARGET MbedTLS::mbedx509)
|
||||
set(MbedCrypto_TARGET MbedTLS::mbedcrypto)
|
||||
|
||||
find_package_handle_standard_args(MbedTLS REQUIRED_VARS ${_MBED_REQUIRED_VARS})
|
||||
mark_as_advanced(${_MBED_REQUIRED_VARS})
|
||||
|
173
external/nng/cmake/NNGHelpers.cmake
vendored
Normal file
173
external/nng/cmake/NNGHelpers.cmake
vendored
Normal file
|
@ -0,0 +1,173 @@
|
|||
#
|
||||
# Copyright 2024 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_find_package looks up required package and adds dependency to the cmake config.
|
||||
macro(nng_find_package PACKAGE_NAME)
|
||||
find_package(${PACKAGE_NAME} REQUIRED)
|
||||
list(APPEND NNG_PKGS ${PACKAGE_NAME})
|
||||
list(REMOVE_DUPLICATES NNG_PKGS)
|
||||
set(NNG_PKGS ${NNG_PKGS} CACHE INTERNAL "nng package dependencies" FORCE)
|
||||
endmacro()
|
||||
|
||||
# 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()
|
||||
|
||||
function(nng_link_libraries_public)
|
||||
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)
|
153
external/nng/cmake/NNGOptions.cmake
vendored
Normal file
153
external/nng/cmake/NNGOptions.cmake
vendored
Normal file
|
@ -0,0 +1,153 @@
|
|||
#
|
||||
# Copyright 2024 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)
|
||||
|
||||
# Turning off the compatibility layer can save some space, and
|
||||
# compilation time, but may break legacy applications It should
|
||||
# be left enabled when building a shared library.
|
||||
option(NNG_ENABLE_COMPAT "Enable legacy nanomsg API." ON)
|
||||
|
||||
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)
|
||||
|
||||
# Some sites or kernels lack IPv6 support. This override allows us
|
||||
# to prevent the use of IPv6 in environments where it isn't supported.
|
||||
option (NNG_ENABLE_IPV6 "Enable IPv6." ON)
|
||||
mark_as_advanced(NNG_ENABLE_IPV6)
|
||||
|
||||
#
|
||||
# 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)
|
||||
|
||||
option (NNG_TRANSPORT_FDC "Enable File Descriptor transport (EXPERIMENTAL)" ON)
|
||||
mark_as_advanced(NNG_TRANSPORT_FDC)
|
||||
|
||||
# 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 2023 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_MAJOR_VERSION "@NNG_MAJOR_VERSION@")
|
||||
set(NNG_MINOR_VERSION "@NNG_MINOR_VERSION@")
|
||||
set(NNG_PATCH_VERSION "@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@)
|
27
external/nng/demo/async/CMakeLists.txt
vendored
Normal file
27
external/nng/demo/async/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
#
|
||||
# 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.12)
|
||||
|
||||
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)
|
||||
|
||||
find_package(Threads)
|
||||
|
||||
add_executable(server server.c)
|
||||
target_link_libraries(server nng::nng)
|
||||
target_compile_definitions(server PRIVATE NNG_ELIDE_DEPRECATED PARALLEL=${PARALLEL})
|
||||
|
||||
add_executable(client client.c)
|
||||
target_link_libraries(client nng::nng)
|
||||
target_compile_definitions(client PRIVATE NNG_ELIDE_DEPRECATED)
|
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_sendmsg", 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 @@
|
|||
#!/usr/bin/env 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);
|
||||
}
|
21
external/nng/demo/http_client/CMakeLists.txt
vendored
Normal file
21
external/nng/demo/http_client/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
#
|
||||
# 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.12)
|
||||
|
||||
project(http_client)
|
||||
|
||||
# Call this from your own project's makefile.
|
||||
find_package(nng CONFIG REQUIRED)
|
||||
|
||||
find_package(Threads)
|
||||
|
||||
add_executable(http_client http_client.c)
|
||||
target_link_libraries(http_client nng::nng)
|
||||
target_compile_definitions(http_client PRIVATE NNG_ELIDE_DEPRECATED)
|
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);
|
||||
}
|
18
external/nng/demo/pubsub_forwarder/CMakeLists.txt
vendored
Normal file
18
external/nng/demo/pubsub_forwarder/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
# 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 3.10)
|
||||
project(pubsub_forwarder C)
|
||||
|
||||
# Find the nng library
|
||||
find_package(nng REQUIRED)
|
||||
|
||||
# Add the executable target
|
||||
add_executable(pubsub_forwarder pubsub_forwarder.c)
|
||||
|
||||
target_compile_options(pubsub_forwarder PRIVATE -Wall -Wextra -Wpedantic -Werror -O2)
|
||||
|
||||
# Link against the nng library
|
||||
target_link_libraries(pubsub_forwarder PRIVATE nng)
|
62
external/nng/demo/pubsub_forwarder/README.adoc
vendored
Normal file
62
external/nng/demo/pubsub_forwarder/README.adoc
vendored
Normal file
|
@ -0,0 +1,62 @@
|
|||
= PubSub Forwarder
|
||||
|
||||
This is a trivial example of a forwarder/proxy for the pub/sub pattern.
|
||||
|
||||
The concept is as follows: the forwarder will listen for connections on
|
||||
both a front-end port and a back-end port. The front-end will act as a
|
||||
subscriber so that publishers can publish to it. The back-end will act
|
||||
as a publisher so that subscribers can subscribe to it. The front-end
|
||||
then forwards to the back end.
|
||||
|
||||
== Compiling
|
||||
|
||||
CMake with ninja-build is simplest:
|
||||
|
||||
[source, bash]
|
||||
----
|
||||
cmake -GNinja -B build
|
||||
cd build
|
||||
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} pubsub_forwarder.c -o pubsub_forwarder ${LDFLAGS}
|
||||
----
|
||||
|
||||
== Running
|
||||
|
||||
An example setup for running this example would involve the following:
|
||||
|
||||
. Step 1: Run this example binary (in the background or a terminal, etc)
|
||||
. Step 2: In a new terminal, run the following
|
||||
|
||||
[source, bash]
|
||||
----
|
||||
nngcat --sub --dial "tcp://localhost:3328" --quoted
|
||||
----
|
||||
|
||||
. Step 3: In a second terminal, run the same command again to give us two subscribers
|
||||
|
||||
[source, bash]
|
||||
----
|
||||
nngcat --sub --dial "tcp://localhost:3328" --quoted
|
||||
----
|
||||
|
||||
|
||||
. In a third terminal, run the following to publish a counter
|
||||
|
||||
[source, bash]
|
||||
----
|
||||
for n in $(seq 0 99); do nngcat --pub --dial "tcp://localhost:3327" --data "$n"; done
|
||||
----
|
||||
|
||||
|
||||
|
96
external/nng/demo/pubsub_forwarder/pubsub_forwarder.c
vendored
Normal file
96
external/nng/demo/pubsub_forwarder/pubsub_forwarder.c
vendored
Normal file
|
@ -0,0 +1,96 @@
|
|||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
//
|
||||
// Forwarder example based on https://github.com/C-o-r-E/nng_pubsub_proxy
|
||||
//
|
||||
// This example shows how to use raw sockets to set up a forwarder or proxy for
|
||||
// pub/sub.
|
||||
//
|
||||
// An example setup for running this example would involve the following:
|
||||
//
|
||||
// - Run this example binary (in the background or a terminal, etc)
|
||||
// - In a new terminal, run
|
||||
// `nngcat --sub --dial "tcp://localhost:3328" --quoted`
|
||||
// - In a second terminal, run
|
||||
// `nngcat --sub --dial "tcp://localhost:3328" --quoted`
|
||||
// - In a third terminal, run
|
||||
// `for n in $(seq 0 99);`
|
||||
// `do nngcat --pub --dial "tcp://localhost:3327" --data "$n";`
|
||||
// `done`
|
||||
//
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <nng/nng.h>
|
||||
#include <nng/protocol/pubsub0/pub.h>
|
||||
#include <nng/protocol/pubsub0/sub.h>
|
||||
|
||||
#define PROXY_FRONT_URL "tcp://localhost:3327"
|
||||
#define PROXY_BACK_URL "tcp://localhost:3328"
|
||||
|
||||
void
|
||||
panic_on_error(int should_panic, const char *format, ...)
|
||||
{
|
||||
if (should_panic) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vprintf(format, args);
|
||||
va_end(args);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
nng_socket sock_front_end = NNG_SOCKET_INITIALIZER;
|
||||
nng_socket sock_back_end = NNG_SOCKET_INITIALIZER;
|
||||
int ret = 0;
|
||||
|
||||
//
|
||||
// First we need some nng sockets. Not to be confused with network
|
||||
// sockets
|
||||
//
|
||||
ret = nng_sub0_open_raw(&sock_front_end);
|
||||
panic_on_error(ret, "Failed to open front end socket\n");
|
||||
|
||||
ret = nng_pub0_open_raw(&sock_back_end);
|
||||
panic_on_error(ret, "Failed to open back end socket\n");
|
||||
|
||||
//
|
||||
// Now we need to set up a listener for each socket so that they have
|
||||
// addresses
|
||||
//
|
||||
|
||||
nng_listener front_ls = NNG_LISTENER_INITIALIZER;
|
||||
nng_listener back_ls = NNG_LISTENER_INITIALIZER;
|
||||
|
||||
ret = nng_listener_create(&front_ls, sock_front_end, PROXY_FRONT_URL);
|
||||
panic_on_error(ret, "Failed to create front listener\n");
|
||||
|
||||
ret = nng_listener_create(&back_ls, sock_back_end, PROXY_BACK_URL);
|
||||
panic_on_error(ret, "Failed to create back listener\n");
|
||||
|
||||
ret = nng_listener_start(front_ls, 0);
|
||||
panic_on_error(ret, "Failed to start front listener\n");
|
||||
|
||||
ret = nng_listener_start(back_ls, 0);
|
||||
panic_on_error(ret, "Failed to start back listener\n");
|
||||
|
||||
//
|
||||
// Finally let nng do the forwarding/proxying
|
||||
//
|
||||
|
||||
ret = nng_device(sock_front_end, sock_back_end);
|
||||
panic_on_error(
|
||||
ret, "nng_device returned %d: %s\n", ret, nng_strerror(ret));
|
||||
|
||||
printf("done");
|
||||
return 0;
|
||||
}
|
22
external/nng/demo/raw/CMakeLists.txt
vendored
Normal file
22
external/nng/demo/raw/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.12)
|
||||
|
||||
project(raw)
|
||||
|
||||
set(PARALLEL 128 CACHE STRING "Parallelism (min 4, max 1000)")
|
||||
|
||||
find_package(nng CONFIG REQUIRED)
|
||||
|
||||
find_package(Threads)
|
||||
|
||||
add_executable(raw raw.c)
|
||||
target_link_libraries(raw nng::nng)
|
||||
target_compile_definitions(raw PRIVATE NNG_ELIDE_DEPRECATED PARALLEL=${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);
|
||||
}
|
23
external/nng/demo/reqrep/CMakeLists.txt
vendored
Normal file
23
external/nng/demo/reqrep/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
#
|
||||
# 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.12)
|
||||
|
||||
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)
|
||||
target_compile_definitions(reqrep PRIVATE NNG_ELIDE_DEPRECATED)
|
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_set_string(listener, NNG_OPT_ZT_HOME, ".");
|
||||
nng_listener_set_ms(listener, NNG_OPT_RECONNMINT, 1);
|
||||
nng_listener_set_ms(listener, NNG_OPT_RECONNMAXT, 1000);
|
||||
nng_socket_set_ms(sock, NNG_OPT_REQ_RESENDTIME, 2000);
|
||||
nng_socket_set_ms(sock, NNG_OPT_RECVMAXSZ, 0);
|
||||
nng_listener_set_ms(listener, NNG_OPT_ZT_PING_TIME, 10000);
|
||||
nng_listener_set_ms(listener, NNG_OPT_ZT_CONN_TIME, 1000);
|
||||
} else {
|
||||
nng_socket_set_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_set_string(dialer, NNG_OPT_ZT_HOME, ".");
|
||||
nng_dialer_set_ms(dialer, NNG_OPT_RECONNMINT, 1);
|
||||
nng_dialer_set_ms(dialer, NNG_OPT_RECONNMAXT, 1000);
|
||||
nng_socket_set_ms(sock, NNG_OPT_REQ_RESENDTIME, 2000);
|
||||
nng_socket_set_ms(sock, NNG_OPT_RECVMAXSZ, 0);
|
||||
nng_dialer_set_ms(dialer, NNG_OPT_ZT_PING_TIME, 10000);
|
||||
nng_dialer_set_ms(dialer, NNG_OPT_ZT_CONN_TIME, 1000);
|
||||
} else {
|
||||
nng_socket_set_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);
|
||||
}
|
20
external/nng/demo/rest/CMakeLists.txt
vendored
Normal file
20
external/nng/demo/rest/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.12)
|
||||
|
||||
project(rest)
|
||||
|
||||
find_package(nng CONFIG REQUIRED)
|
||||
|
||||
find_package(Threads)
|
||||
|
||||
add_executable(rest-server server.c)
|
||||
target_link_libraries(rest-server nng::nng)
|
||||
target_compile_definitions(rest-server PRIVATE NNG_ELIDE_DEPRECATED)
|
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 NOP 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);
|
||||
}
|
27
external/nng/demo/stream/CMakeLists.txt
vendored
Normal file
27
external/nng/demo/stream/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
#
|
||||
# Copyright 2020 Hugo Lindström <hugolm84@gmail.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.
|
||||
|
||||
cmake_minimum_required (VERSION 2.8.7)
|
||||
|
||||
project(stream)
|
||||
|
||||
find_package(nng CONFIG REQUIRED)
|
||||
|
||||
add_executable(${PROJECT_NAME})
|
||||
|
||||
target_sources(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/stream.c)
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
target_sources(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/platform/posix/server.c)
|
||||
endif()
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||
target_sources(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/platform/windows/server.c)
|
||||
endif()
|
||||
|
||||
target_link_libraries(stream nng::nng)
|
53
external/nng/demo/stream/platform/posix/server.c
vendored
Normal file
53
external/nng/demo/stream/platform/posix/server.c
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
// Copyright 2020 Hugo Lindström <hugolm84@gmail.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.
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void
|
||||
error(const char *msg)
|
||||
{
|
||||
perror(msg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
server(int portno)
|
||||
{
|
||||
int sockfd, newsockfd;
|
||||
socklen_t clilen;
|
||||
struct sockaddr_in serv_addr, cli_addr;
|
||||
int n;
|
||||
sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sockfd < 0) {
|
||||
error("ERROR opening socket");
|
||||
}
|
||||
bzero((char *) &serv_addr, sizeof(serv_addr));
|
||||
serv_addr.sin_family = AF_INET;
|
||||
serv_addr.sin_addr.s_addr = INADDR_ANY;
|
||||
serv_addr.sin_port = htons(portno);
|
||||
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) <
|
||||
0) {
|
||||
error("ERROR on binding");
|
||||
}
|
||||
listen(sockfd, 5);
|
||||
clilen = sizeof(cli_addr);
|
||||
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
|
||||
if (newsockfd < 0) {
|
||||
error("ERROR on accept");
|
||||
}
|
||||
n = write(newsockfd, "Hello Client!", 13);
|
||||
if (n < 0)
|
||||
error("ERROR writing to socket");
|
||||
close(newsockfd);
|
||||
close(sockfd);
|
||||
return 0;
|
||||
}
|
87
external/nng/demo/stream/platform/windows/server.c
vendored
Normal file
87
external/nng/demo/stream/platform/windows/server.c
vendored
Normal file
|
@ -0,0 +1,87 @@
|
|||
// Copyright 2020 Hugo Lindström <hugolm84@gmail.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.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <winsock2.h>
|
||||
|
||||
void
|
||||
wsa_fatal(const char *func)
|
||||
{
|
||||
fprintf(stderr, "%s: %d\n", func, WSAGetLastError());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
server(int portno)
|
||||
{
|
||||
WSADATA wsa;
|
||||
SOCKET s, new_socket;
|
||||
struct sockaddr_in server, client;
|
||||
int c;
|
||||
char * message;
|
||||
|
||||
printf("Initialising Winsock...\n");
|
||||
|
||||
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) {
|
||||
wsa_fatal("Failed to call WSAStartup");
|
||||
}
|
||||
|
||||
printf("Initialised WSA.\n");
|
||||
|
||||
// Create a socket
|
||||
if ((s = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
|
||||
wsa_fatal("Could not create socket");
|
||||
}
|
||||
|
||||
printf("Socket created.\n");
|
||||
|
||||
// Prepare the sockaddr_in structure
|
||||
server.sin_family = AF_INET;
|
||||
server.sin_addr.s_addr = INADDR_ANY;
|
||||
server.sin_port = htons(portno);
|
||||
|
||||
// Bind
|
||||
if (bind(s, (struct sockaddr *) &server, sizeof(server)) ==
|
||||
SOCKET_ERROR) {
|
||||
wsa_fatal("Bind failed");
|
||||
}
|
||||
|
||||
printf("Bind done\n");
|
||||
|
||||
// Listen to incoming connections
|
||||
listen(s, 3);
|
||||
|
||||
// Accept and incoming connection
|
||||
printf("Waiting for incoming connections...\n");
|
||||
|
||||
c = sizeof(struct sockaddr_in);
|
||||
|
||||
while ((new_socket = accept(s, (struct sockaddr *) &client, &c)) !=
|
||||
INVALID_SOCKET) {
|
||||
printf("Connection accepted\n");
|
||||
// Reply to the client
|
||||
message = "Hello Client!";
|
||||
if (send(new_socket, message, (int) strlen(message), 0) ==
|
||||
SOCKET_ERROR) {
|
||||
wsa_fatal("Failed to send message to client!");
|
||||
}
|
||||
}
|
||||
|
||||
if (new_socket == INVALID_SOCKET) {
|
||||
wsa_fatal("accept failed");
|
||||
}
|
||||
|
||||
if (closesocket(s) == SOCKET_ERROR) {
|
||||
wsa_fatal("Failed to close socket");
|
||||
}
|
||||
|
||||
if (WSACleanup() == SOCKET_ERROR) {
|
||||
wsa_fatal("Failed to WSACleanup");
|
||||
}
|
||||
return 0;
|
||||
}
|
109
external/nng/demo/stream/stream.c
vendored
Normal file
109
external/nng/demo/stream/stream.c
vendored
Normal file
|
@ -0,0 +1,109 @@
|
|||
// Copyright 2020 Hugo Lindström <hugolm84@gmail.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 async communication with
|
||||
// an arbitrary socket using nng_stream. The server receives a connection and
|
||||
// sends a hello message to the nng_stream iov.
|
||||
|
||||
// To run this program, start the server as stream -s <portnumber>
|
||||
// Then connect to it with the client as stream -c <url>
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// % ./stream -s 5555 &
|
||||
// % ./stream -c tcp://127.0.0.1:5555
|
||||
|
||||
#include <nng/nng.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
void
|
||||
nng_fatal(const char *func, int rv)
|
||||
{
|
||||
fprintf(stderr, "%s: %s\n", func, nng_strerror(rv));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int server(int port);
|
||||
int client(const char *url);
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "Usage: %s [-s port|-c url]\n", argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (strcmp(argv[1], "-s") == 0) {
|
||||
rc = server(atoi(argv[2]));
|
||||
} else {
|
||||
rc = client(argv[2]);
|
||||
}
|
||||
exit(rc == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
|
||||
}
|
||||
|
||||
int
|
||||
client(const char *url)
|
||||
{
|
||||
nng_stream_dialer *dialer;
|
||||
nng_aio * aio;
|
||||
nng_iov iov;
|
||||
int rv;
|
||||
|
||||
// Allocatate dialer and aio assoicated with this connection
|
||||
if ((rv = nng_stream_dialer_alloc(&dialer, url)) != 0) {
|
||||
nng_fatal("call to nng_stream_dialer_alloc failed", rv);
|
||||
}
|
||||
|
||||
if ((rv = nng_aio_alloc(&aio, NULL, NULL)) != 0) {
|
||||
nng_fatal("call to nng_aio_alloc", rv);
|
||||
}
|
||||
nng_aio_set_timeout(aio, 5000); // 5 sec
|
||||
|
||||
// Allocatate a buffer to recv
|
||||
iov.iov_len = 100;
|
||||
iov.iov_buf = (char *) malloc(sizeof(char) * iov.iov_len);
|
||||
if ((rv = nng_aio_set_iov(aio, 1, &iov)) != 0) {
|
||||
nng_fatal("call to nng_aio_alloc", rv);
|
||||
}
|
||||
// Connect to the socket via url provided to alloc
|
||||
nng_stream_dialer_dial(dialer, aio);
|
||||
|
||||
// Wait for connection
|
||||
nng_aio_wait(aio);
|
||||
if ((rv = nng_aio_result(aio)) != 0) {
|
||||
nng_fatal("waiting for ng_stream_dialer_dial failed", rv);
|
||||
}
|
||||
|
||||
// Get the stream (connection) at position 0
|
||||
nng_stream *c1 = (nng_stream *) nng_aio_get_output(aio, 0);
|
||||
nng_stream_recv(c1, aio);
|
||||
nng_aio_wait(aio);
|
||||
if ((rv = nng_aio_result(aio)) != 0) {
|
||||
nng_fatal("waiting for nng_stream_recv failed", rv);
|
||||
}
|
||||
|
||||
size_t recv_count = nng_aio_count(aio);
|
||||
if (recv_count <= 0) {
|
||||
nng_fatal("Recv count was 0!", NNG_ECONNABORTED);
|
||||
} else {
|
||||
printf("received %zu bytes, message: '%s'\n", recv_count,
|
||||
(char *) iov.iov_buf);
|
||||
}
|
||||
|
||||
// Send ELCOSE to send/recv associated wit this stream
|
||||
free(iov.iov_buf);
|
||||
nng_stream_free(c1);
|
||||
nng_aio_free(aio);
|
||||
nng_stream_dialer_free(dialer);
|
||||
return 0;
|
||||
}
|
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 TLS 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 https://tls.mbed.org/[Mbed TLS]
|
||||
library.
|
||||
|
||||
IMPORTANT: Mbed TLS 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 Mbed TLS. 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 Mbed TLS from source; if you choose to do so,
|
||||
please make sure you also *install* it somewhere (even a temporary
|
||||
staging directory).
|
||||
|
||||
== Configuring NNG with Mbed TLS
|
||||
|
||||
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 Mbed TLS in `/usr/local`,
|
||||
as well as the normal installation directories for libraries on your system.
|
||||
|
||||
If you have installed Mbed TLS 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 Mbed TLS 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.
|
446
external/nng/docs/man/CMakeLists.txt
vendored
Normal file
446
external/nng/docs/man/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,446 @@
|
|||
#
|
||||
# Copyright 2024 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_log
|
||||
nng_log_get_level
|
||||
nng_log_set_facility
|
||||
nng_log_set_level
|
||||
nng_log_set_logger
|
||||
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_str_sockaddr
|
||||
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_id_map
|
||||
nng_msleep
|
||||
nng_mtx_alloc
|
||||
nng_mtx_free
|
||||
nng_mtx_lock
|
||||
nng_mtx_unlock
|
||||
nng_opts_parse
|
||||
nng_random
|
||||
nng_socket_pair
|
||||
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_socket
|
||||
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 ()
|
484
external/nng/docs/man/libnng.3.adoc
vendored
Normal file
484
external/nng/docs/man/libnng.3.adoc
vendored
Normal file
|
@ -0,0 +1,484 @@
|
|||
= libnng(3)
|
||||
//
|
||||
// Copyright 2023 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_busy.3.adoc[nng_aio_busy()]|test if asynchronous I/O is busy
|
||||
|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_recvmsg.3.adoc[nng_ctx_recvmsg()]|receive a message using context
|
||||
|xref:nng_ctx_send.3.adoc[nng_ctx_send()]|send message using context asynchronously
|
||||
|xref:nng_ctx_sendmsg.3.adoc[nng_ctx_sendmsg()]|send a message using context
|
||||
|xref:nng_ctx_set.3.adoc[nng_ctx_set()]|set context option
|
||||
|xref:nng_ctx_setopt.3.adoc[nng_ctx_setopt()]|set context option
|
||||
|===
|
||||
|
||||
=== Devices, Relays
|
||||
|
||||
The following function family is used to create forwarders or relayers
|
||||
that route messages from one socket to another.
|
||||
|
||||
|===
|
||||
|xref:nng_device.3.adoc[nng_device()]|message forwarding device
|
||||
|===
|
||||
|
||||
=== 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
|
||||
|===
|
||||
|
||||
=== Logging Support
|
||||
|
||||
Common functionality for message logging.
|
||||
|
||||
|===
|
||||
|xref:nng_log.3.adoc[nng_log()]|log a message
|
||||
|xref:nng_log_facility.3.adoc[nng_log_set_facility()]|set log facility
|
||||
|xref:nng_log_level.3.adoc[nng_log_set_level()]|set log level
|
||||
|xref:nng_log_logger.3.adoc[nng_log_set_logger()]|set logging handler
|
||||
|===
|
||||
|
||||
=== 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_id_map.3supp.adoc[nng_id_map]|identifier based mapping table
|
||||
|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_socket_pair.3supp.adoc[nng_socket_pair()]|create connected pair of BSD sockets
|
||||
|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)]
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue