nanomsg-next-generation -- light-weight brokerless messaging

Overview

nng - nanomsg-next-gen

Linux Status Windows Status macOS Status Coverage Codacy LGTM Discord Manual MIT License Latest version

ℹ️
If you are looking for the legacy version of nanomsg, please see the nanomsg repository.

This project is a rewrite of the Scalability Protocols library known as 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 nanomsg (and to some extent 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":

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 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 CMake version 3.13 or newer.

We recommend using the 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 mbedTLS. See docs/BUILD_TLS.adoc for details.

Quick Start

With a Linux or UNIX environment:

  $ 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 online. The libnng(3) page is a good starting point.

You can also purchase a copy of the 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 nng_compat(3) for details.

Commercial Support

Commercial support for NNG is available.

Please contact Staysail Systems to inquire further.

Commercial Sponsors

The development of NNG has been made possible through the generous sponsorship of Capitar IT Group BV and Staysail Systems, Inc..

Issues
  • Reproducing IPC transport unit tests causing INFINITE lock wait

    Reproducing IPC transport unit tests causing INFINITE lock wait

    Couched in my understanding that the API isn't quite ready yet. This may be one of those areas, I don't know.

    Whether following the C-style calls or the C++ wrapper, it does not seem to matter. Something in the way the testing is initialized "under the hood" is causing the tests to hang INFINITE-ly.

    When there is a valid listen/dial pair in effect, the dial operation hangs INFINITE-ly. Debugging gets as far as nni_ep_dial(...) and the subsequent nni_aoi_wait(...). Which then waits with INFINITE options on the call to SleepConditionVariableSRW.

    // Gets as far as here...
    int nni_ep_dial(nni_ep *ep, int flags)
    
    // Then blocks indefinitely on the (synchronous?) AOI to return.
    nni_aio_wait(aio);
    
    // Ultimately waiting on a condition variable that is never cleared, apparently.
    // And with "INFINITE" timeout? not otherwise queued on the socket options? i.e. timeouts?
    void
    nni_plat_cv_wait(nni_plat_cv *cv)
    {
      (void) SleepConditionVariableSRW(&cv->cv, cv->srl, INFINITE, 0);
    }
    

    TCP works great. So does INPROC. IPC, on the other hand, is problematic under Windows (i.e. Windows 7 x64).

    The only difference I can determine at this point is in how the NNG IPC transport tests are initialized.

    void
    trantest_init(trantest *tt, const char *addr)
    {
      trantest_next_address(tt->addr, addr);
      So(nng_req_open(&tt->reqsock) == 0); // These look innocent enough.
      So(nng_rep_open(&tt->repsock) == 0);
    
      tt->tran = nni_tran_find(addr); // This however I find suspicious.
      So(tt->tran != NULL); // And/or perhaps something in the way that the project is build, flags, etc.
    }
    
    opened by mwpowellhtx 61
  • nng_recv() sometimes acts on null `msg` pointer

    nng_recv() sometimes acts on null `msg` pointer

    NNG & Platform details.

    NNG commit 6401d100e8b616c65014ae7fd62ac9a575466bef Windows 10 (RS3, 10.0.16299) using from C++

    Expected Behavior

    No segfault in nng_recv on calling nng_msg_len.

    Actual Behavior

    Segfault, nng_recvmsg rv = 0, msg = NULL.

    Steps to Reproduce

    Haven't found a minimal repro yet, however some details on our usage:

    • 2 threads, let's name them 'main' and 'net'
    • each thread owns a client req (our understanding is this allows resending?) inproc:// socket to the thread's rep socket (inproc://net and inproc://main)
    • 4-byte messages get sent to signal wakeup, no other data is sent at this time
    • recv call:
    					while (nng_recv(netSocket, &msgBuffer, &msgLen, NNG_FLAG_NONBLOCK | NNG_FLAG_ALLOC) == 0)
    					{
    						nng_free(msgBuffer, msgLen);
    
    						int ok = 0;
    						nng_send(netSocket, &ok, 4, NNG_FLAG_NONBLOCK);
    
    						m_netThreadCallbacks.Run();
    					}
    
    • send call:
    		nng_send(sockets[i], &idxList[0], idxList.size() * sizeof(int), NNG_FLAG_NONBLOCK);
    

    We're also having some other issues with aio lifetime on both Linux and Windows - possibly some kind of use-after-free or double frees, but no actual coredump at hand for this. 😕

    bug 
    opened by blattersturm 39
  • SIGSEGV in RepReq's rep0 recv - use after free

    SIGSEGV in RepReq's rep0 recv - use after free

    As briefly discussed in #1240 there appears to be a bug in the current implementation that results in a SIGSEGV when a socket is closed but the resend timeout fired at least once. Or that is my current theory on it at least.

    SIGSEGV from C implementation:

    https://gist.github.com/AlexKornitzer/371eef55e558e89d10850d53986dfb35
    
    ./reqrep server ipc:///tmp/abcd 
    ./reqrep client ipc:///tmp/abcd
    
    panic: pthread_mutex_lock: Invalid argument
    This message is indicative of a BUG.
    Report this at https://github.com/nanomsg/nng/issues
    /home/developer/Developer/scratch/nng/reqrep(+0x15bb9) [0x555555569bb9]
    /home/developer/Developer/scratch/nng/reqrep(+0x1f7af) [0x5555555737af]
    /home/developer/Developer/scratch/nng/reqrep(+0x1f958) [0x555555573958]
    /home/developer/Developer/scratch/nng/reqrep(+0x1c826) [0x555555570826]
    /home/developer/Developer/scratch/nng/reqrep(+0x1c562) [0x555555570562]
    /home/developer/Developer/scratch/nng/reqrep(+0xf21f) [0x55555556321f]
    /home/developer/Developer/scratch/nng/reqrep(+0x24617) [0x555555578617]
    /home/developer/Developer/scratch/nng/reqrep(+0x15f4e) [0x555555569f4e]
    /home/developer/Developer/scratch/nng/reqrep(+0xe60d) [0x55555556260d]
    /home/developer/Developer/scratch/nng/reqrep(+0xec35) [0x555555562c35]
    /home/developer/Developer/scratch/nng/reqrep(+0x18a00) [0x55555556ca00]
    /home/developer/Developer/scratch/nng/reqrep(+0x739f) [0x55555555b39f]
    /home/developer/Developer/scratch/nng/reqrep(+0x710d) [0x55555555b10d]
    /home/developer/Developer/scratch/nng/reqrep(+0x6f29) [0x55555555af29]
    /home/developer/Developer/scratch/nng/reqrep(+0x690f) [0x55555555a90f]
    /home/developer/Developer/scratch/nng/reqrep(+0x6dac) [0x55555555adac]
    /usr/lib/libc.so.6(__libc_start_main+0xf3) [0x7ffff7ded023]
    /home/developer/Developer/scratch/nng/reqrep(+0x672e) [0x55555555a72e]
    
    (gdb) bt
    #0  0x00007ffff7e01ce5 in raise () from /usr/lib/libc.so.6
    #1  0x00007ffff7deb857 in abort () from /usr/lib/libc.so.6
    #2  0x00005555555733bf in nni_plat_abort ()
    #3  0x0000555555569bbe in nni_panic ()
    #4  0x00005555555737af in nni_pthread_mutex_lock ()
    #5  0x0000555555573958 in nni_plat_mtx_lock ()
    #6  0x0000555555570826 in nni_mtx_lock ()
    #7  0x0000555555570562 in nni_task_dispatch ()
    #8  0x000055555556321f in nni_aio_begin ()
    #9  0x0000555555578617 in ipctran_pipe_recv ()
    #10 0x0000555555569f4e in nni_pipe_recv ()
    #11 0x000055555556260d in rep0_ctx_recv ()
    #12 0x0000555555562c35 in rep0_sock_recv ()
    #13 0x000055555556ca00 in nni_sock_recv ()
    #14 0x000055555555b39f in nng_recv_aio ()
    #15 0x000055555555b10d in nng_recvmsg ()
    #16 0x000055555555af29 in nng_recv ()
    #17 0x000055555555a90f in server ()
    #18 0x000055555555adac in main ()
    

    SIGSEGV from Rust version:

    Thread 1 "scratch" received signal SIGSEGV, Segmentation fault.
    0x0000555555577ce4 in nni_pipe_recv (p=0x0, aio=0x7fffe8001430)
        at /home/developer/.cargo/registry/src/github.com-1ecc6299db9ec823/nng-sys-1.2.4-rc.1/nng/src/core/pipe.c:141
    141             p->p_tran_ops.p_recv(p->p_tran_data, aio);
    (gdb) bt
    #0  0x0000555555577ce4 in nni_pipe_recv (p=0x0, aio=0x7fffe8001430)
        at /home/developer/.cargo/registry/src/github.com-1ecc6299db9ec823/nng-sys-1.2.4-rc.1/nng/src/core/pipe.c:141
    #1  0x000055555556dddf in rep0_ctx_recv (arg=0x5555555ead20, aio=0x5555555edcb0)
        at /home/developer/.cargo/registry/src/github.com-1ecc6299db9ec823/nng-sys-1.2.4-rc.1/nng/src/protocol/reqrep0/rep.c:504
    #2  0x000055555556e361 in rep0_sock_recv (arg=0x5555555eac10, aio=0x5555555edcb0)
        at /home/developer/.cargo/registry/src/github.com-1ecc6299db9ec823/nng-sys-1.2.4-rc.1/nng/src/protocol/reqrep0/rep.c:670
    #3  0x000055555557ade3 in nni_sock_recv (sock=0x5555555ea220, aio=0x5555555edcb0)
        at /home/developer/.cargo/registry/src/github.com-1ecc6299db9ec823/nng-sys-1.2.4-rc.1/nng/src/core/socket.c:847
    #4  0x00005555555666e6 in nng_recv_aio (s=..., aio=0x5555555edcb0)
        at /home/developer/.cargo/registry/src/github.com-1ecc6299db9ec823/nng-sys-1.2.4-rc.1/nng/src/nng.c:214
    #5  0x000055555556651d in nng_recvmsg (s=..., msgp=0x7fffffffcf50, flags=0)
        at /home/developer/.cargo/registry/src/github.com-1ecc6299db9ec823/nng-sys-1.2.4-rc.1/nng/src/nng.c:136
    #6  0x0000555555564a84 in nng::socket::Socket::recv (self=0x7fffffffd018)
        at /home/developer/.cargo/git/checkouts/nng-rs-585a5382ec72d3dc/fc301c2/src/socket.rs:245
    #7  0x00005555555600f1 in scratch::server () at src/main.rs:76
    #8  0x0000555555560339 in scratch::main () at src/main.rs:87
    
    bug 
    opened by alexkornitzer 39
  • IPC error during Bus tests

    IPC error during Bus tests

    2017.11.04 17:55:10.830   ERROR Process C:\Users\Michael\AppData\Local\JetBrains\Installations\ReSharperPlatformVs14\JetBrains.ReSharper.TaskRunner.CLR45.x64.exe:14588 exited with code '3':
    panic: G:\Source\Spikes\nanomsg\csnng\prototype\repos\nng\src\platform\windows\win_ipc.c: 65: assert err: aio->a_iov[0].iov_len
    This message is indicative of a BUG.
    Report this at http://github.com/nanomsg/nanomsg
    

    Test log:

    Running protocol tests for address family 'InterProcess'.
    Testing using address 'ipc://pipe/325656c3-4e60-4c89-81d4-097e4a20dfa2'.
    Given three Nanomsg2.Sharp.Protocols.Bus.LatestBusSocket instances.
      And messages can be delivered.
        And receive times out.
          And Bus1 delivers message to both Bus2 and Bus3.
    

    Based on IPC specialized Bus tests:

    namespace Nanomsg2.Sharp.Protocols.Bus
    {
        using Xunit.Abstractions;
    
        public class InterProcessBusTests : BusTests
        {
            protected override SocketAddressFamily Family { get; } = SocketAddressFamily.InterProcess;
    
            public InterProcessBusTests(ITestOutputHelper @out)
                : base(@out)
            {
            }
        }
    }
    

    Running under Visual Studio 2015, C# 6.0, xUnit, Windows 7 Professional (x64).

    opened by mwpowellhtx 33
  • [Question] req/rep inverted async demo

    [Question] req/rep inverted async demo

    Hello,

    I'm filing this issue to have an answer for a question that I have: I have a very similar need than the one described in the async demo. The only slight difference is that my server is actually a REQ and my clients are REPs.

    I've first prototyped this in my project and realized that the library was behaving weird so I figured I'd try to make something smaller. I modified the async demo to do just that: make the server a REQ instead of a REP; instead of receiving then sending, it sends, then receives. Also modified the client to accommodate that.

    To give a few more details on what I'm seeing (I haven't really debugged nor tried to find where / why this is happening yet): if I have X aio waiting on a recv (to be able to handle X simultaneous clients) and a client comes, the response of the server gets sent more than once; once with the expected nng_ctx but I can also see the same data getting sent with other nng_ctxs as well (I simply display the context identifier).

    Before I write a reproducer, is the above expected to work, or is there some sort of limitation / something I misunderstood along the way regarding the APIs/REQ/REP? FWIW I am doing my tests with the latest release which is v1.3.2; and I've verified that the same things happen on both Linux / Windows with the tcp transport.

    Cheers

    question feedback 
    opened by 0vercl0k 30
  • kqueue: add kqueue-based pollq implementation

    kqueue: add kqueue-based pollq implementation

    Initial cut at kqueue support for #35

    This passes all tests on my machine, will see how it does on CI. Happy to rename/reorg as needed.

    A couple thoughts:

    • since some of the poller API (add, remove, enable, disable) may involve syscalls, it would nice to return errors from those routines and handle them accordingly, possibly in a future PR
    • i wasn't totally clear on the expected handling of event flags - it looks like the existing poll implementation treats event flag manipulation as a cheap operation (it just manipulates userspace memory in the poll implementation), but since epoll and kqueue implementations might prefer to use the provided syscall interfaces to enable/disable events as distinct from adding/removing nodes, it could be nice to take that into consideration and minimize changes to enable/disable state.
    opened by liamstask 29
  • PUB/SUB Multi-Message Handling

    PUB/SUB Multi-Message Handling

    When porting a script from zmq to pynng (much nicer python coding experience) to broadcast data (bursts of 4 direct follow up messages per loop, approx. 60 loops/s, approx. 1 KB/s TCP traffic) from a PUB to two SUBs, I experienced an unmissable data/message loss that was not experienced with zmq.

    In followup investigations on this topic I found some issues in the nanomsg repository describing this problem (nanomsg/nanomsg#283, nanomsg/nanomsg#390).

    I was wondering, if this "behavior" is still expected to happen with nng. Probably yes, as of #762 and the Conceptual Overview section of the nng manual:

    nng sockets are message oriented, so that messages are either delivered wholly, or not at all. Partial delivery is not possible. Furthermore, nng does not provide any other delivery or ordering guarantees; messages may be dropped or reordered. (Some protocols, such as nng_req(7) may offer stronger guarantees by performing their own retry and validation schemes.)

    NNG & Platform details.

    NNG: Using pynng (codypiersall/[email protected]) and the nng version shipped with it. OS: Windows 10 10.0.17134 (64-Bit) PL: Python 3.7.0

    Expected Behavior

    Not drop 0.5 % (or even 75 %) of messages.

    Actual Behavior

    Drops 0.5 % (or even 75 %) of messages.

    Steps to Reproduce

    The following python code compares the percentage of dropped messages between nng and zmq

    Single Message Example

    import pynng  # From commit 61c9f11
    import zmq
    import time
    
    pub = pynng.Pub0(listen='tcp://*:5555')
    
    sub = pynng.Sub0(dial='tcp://localhost:5555')
    sub.subscribe(b'0')
    
    time.sleep(1)
    
    i_send = 0
    i_recv = 0
    try:
        while True:
            i_send += 1
            
            pub.send(b'0')
            # time.sleep(0.000001)  # Cures the loss
            
            try:
                msg = sub.recv(block=False)
                i_recv += 1
            except pynng.exceptions.TryAgain:
                pass
            
            print(f'pynng: Lost {i_send - i_recv} of {i_send} msgs ' + '({0:3.3f} % loss)'.format((i_send - i_recv) / i_send * 100) + '  [Exit with Ctrl+C]', end='\r')
            if i_send >= 10**6:
                break
    except KeyboardInterrupt:
        pass
    finally:
        print()
        sub.close()
        pub.close()
        time.sleep(1)
    
    
    ctx = zmq.Context()
    
    pub = ctx.socket(zmq.PUB)
    pub.bind('tcp://*:5555')
    
    sub = ctx.socket(zmq.SUB)
    sub.connect('tcp://localhost:5555')
    sub.setsockopt(zmq.SUBSCRIBE, b'0')
    
    time.sleep(1)
    
    i_send = 0
    i_recv = 0
    try:
        while True:
            i_send += 1
            
            pub.send(b'0')
            # time.sleep(0.000001)  # Cures the loss
    
            try:
                msg = sub.recv(zmq.NOBLOCK)
                i_recv += 1
            except zmq.error.Again:
                pass
            
            print(f'zmq:   Lost {i_send - i_recv} of {i_send} msgs ' + '({0:3.3f} % loss)'.format((i_send - i_recv) / i_send * 100) + '  [Exit with Ctrl+C]', end='\r')
            if i_send >= 10**6:
                break
    except KeyboardInterrupt:
        pass
    finally:
        sub.close()
        pub.close()
        time.sleep(1)
    
    exit()
    

    Yielding quite reproducibly the following values:

     pynng: Lost 5258 of 1000000 messages (0.526 % loss)  [Exit with Ctrl+C]
     zmq:   Lost 45 of 1000000 messages (0.005 % loss)  [Exit with Ctrl+C]
    

    Quite interestingly, zmq manages to handle this fast PUB/SUB by 2 orders of magnitude better than nng. A short time.sleep() after send cures the loss in both cases, however, dramatically slows down the script.

    Message Burst Example

    The following script simulates the beforehand mentioned 4 message data bursts:

    import pynng  # From commit 61c9f11
    import zmq
    import time
    
    burstsize = 4
    
    pub = pynng.Pub0(listen='tcp://*:5555')
    
    sub = pynng.Sub0(dial='tcp://localhost:5555')
    sub.subscribe(b'')
    
    time.sleep(1)
    
    i_send = 0
    i_recv = 0
    try:
        while True:
            msgs = []
            for i in range(burstsize):
                i_send += 1
                pub.send(bytes(str(i), encoding='utf-8'))
                # time.sleep(0.000001)  #Leads to 75 % loss - only 1 msg is received!
            
            while True:
                try:
                    msgs += [sub.recv(block=False)]
                    i_recv += 1
                    # time.sleep(0.000001)  # Has no effect
                except pynng.exceptions.TryAgain:
                    break
            
            print(f'pynng: Lost {i_send - i_recv} of {i_send} msgs ' + '({0:3.3f} % loss)  '.format((i_send - i_recv) / i_send * 100) + f'Burst: Recvd {len(msgs)} of {burstsize} msgs ' + '({0:3.3f} % loss)  '.format((burstsize - len(msgs)) / burstsize * 100) + '[Exit with Ctrl+C]', end='\r')
            if i_send >= 10**6:
                break
    except KeyboardInterrupt:
        pass
    finally:
        sub.close()
        pub.close()
        time.sleep(1)
        print()
    
    ctx = zmq.Context()
    
    pub = ctx.socket(zmq.PUB)
    pub.bind('tcp://*:5555')
    
    sub = ctx.socket(zmq.SUB)
    sub.connect('tcp://localhost:5555')
    sub.setsockopt(zmq.SUBSCRIBE, b'')
    
    time.sleep(1)
    
    i_send = 0
    i_recv = 0
    try:
        while True:
            msgs = []
            for i in range(burstsize):
                i_send += 1
                pub.send(bytes(str(i), encoding='utf-8'))
                # time.sleep(0.000001)  # Leads to 75 % loss - only 1 msg is received!
            
            while True:
                try:
                    msgs += [sub.recv(zmq.NOBLOCK)]
                    i_recv += 1
                    # time.sleep(0.000001)  # Has no effect
                except zmq.error.Again:
                    break
            
            print(f'zmq  : Lost {i_send - i_recv} of {i_send} msgs ' + '({0:3.3f} % loss)  '.format((i_send - i_recv) / i_send * 100) + f'Burst: Recvd {len(msgs)} of {burstsize} msgs ' + '({0:3.3f} % loss)  '.format((burstsize - len(msgs)) / burstsize * 100) + '[Exit with Ctrl+C]', end='\r')
            if i_send >= 10**6:
                break
    except KeyboardInterrupt:
        pass
    finally:
        sub.close()
        pub.close()
        time.sleep(1)
    
    exit()
    

    Delivering the following results:

    pynng: Lost 620351 of 1000000 messages (62.035 % loss)  [Exit with Ctrl+C]
    zmq:   Lost 4 of 1000000 messages (0.000 % loss)  [Exit with Ctrl+C]
    

    Again, zmq is the definite winner. In the code example it seems quite random which messages are lost (each of the for different messages are received over time). However, as stated in the code, putting time.sleep() after send, leads to 75 % data loss for nng and the sole message that received is the 1st of the 4 (1 out of 4 = 75 % loss).

    Am I missing some setting here to define a buffer size? Is there any option to make the PUB wait/block until the message was really sent (just sent, not received)?

    As stated by @gdamore in https://github.com/nanomsg/nanomsg/issues/390#issuecomment-98404170

    I'm closing this as the problem is not with nanomsg, but rather with your usage and understanding the limitations of the design.

    a PUB/SUB socket was not the right choice to multicast "a lot of" data in nanomsg, which seemingly still is the case for nng.

    What I thus wonder, and clearly do not understand: If nng's PUB/SUB is not the right choice, what else is?

    As I have to send this data fast and lossless, this issue is the only reason why I have to stick with zmq for my application. (Ok, except for this https://github.com/codypiersall/pynng/issues/9#issuecomment-437969587 - even with some C code from @codypiersall)

    (Sorry for this extremely long issue :) )


    Edit: Code example was 2 × the same. Changed the second to the real burst example.

    feedback 
    opened by lcnittl 28
  • nng_sockaddr_in6 should support 32-bit and 16-bit unionized fields

    nng_sockaddr_in6 should support 32-bit and 16-bit unionized fields

    If I understand my blogs reading according to the spec and the responses I've read, that's the layout, which does appear to care about network byte order. So while 16-byte array is interesting, it is virtually useless to work with.

    See this SO for more detail.

    So, this:

    struct nng_sockaddr_in6 {
        uint16_t sa_family;
        uint16_t sa_port;
        uint8_t  sa_addr[16];
    };
    

    Should probably be something more like this:

    struct nng_sockaddr_in6 {
        uint16_t sa_family;
        uint16_t sa_port;
        union {
            uint8_t sa_addr8[16];
            uint16_t sa_addr16[8];
            uint32_t sa_addr32[4];
        } sa_addr;
    };
    

    Which, actually the 16-bit representation is probably most accurate according to the statement: "An IPv6 address is represented as eight groups of four hexadecimal digits, each group representing 16 bits ".

    Oh, for fun with C/C++ unions.

    Could be wrong.

    opened by mwpowellhtx 28
  • always see 1% message drop on listener

    always see 1% message drop on listener

    NNG Version : 1.1.0

    I did some experiments about how much msg/sec i can pump on a Pair socket with one listener and one dialer. What i found out is irrespective of message size and number of messages per iteration i always see a message drop of around 1%

    iteration | total messages received | total time | msg/sec | drop rate -- | -- | -- | -- | -- 0 | 14927 | 1105 | 13508.60 | 0.49 1 | 14866 | 1072 | 13867.50 | 0.89 2 | 14931 | 1255 | 11897.20 | 0.46 3 | 14965 | 1252 | 11952.90 | 0.23 4 | 14983 | 1101 | 13608.50 | 0.11 5 | 14913 | 1082 | 13782.80 | 0.58 6 | 14919 | 1197 | 12463.70 | 0.54 7 | 14861 | 1067 | 13927.80 | 0.93 8 | 14931 | 1093 | 13660.60 | 0.46 9 | 14900 | 1130 | 13185.80 | 0.67

    these stats are collected on listener and sent back to dialer upon request. Each iteration is attempting to send 15k messages. So if I 4k messages per iteration then receive side would give number in 1% less range. same for any number of messages i send. i thought m

    opened by vk-coder 26
  • Running multiple Bus tests causes error code 3

    Running multiple Bus tests causes error code 3

    Taken individually, InProc, IPv4, or IPv6, the tests all run just fine. But run in parallel causes problems.

    2017.11.04 18:36:17.392   ERROR Process C:\Users\Michael\AppData\Local\JetBrains\Installations\ReSharperPlatformVs14\JetBrains.ReSharper.TaskRunner.CLR45.x64.exe:13608 exited with code '3'.
    

    However, by contrast, the pipeline tests are running just fine, individually, or altogether in parallel (same set as above).

    Generally, I am following the same approach as the C code, closer to the C++ code, probably even a bit "simpler" due no smart pointer gymnastics going on. I am also not bothering to vet any of the protocol/peer stuff, just focusing on messaging, the socket protocols, etc.

    I'll have my repo committed this weekend so you can take a look.

    opened by mwpowellhtx 24
  • bug in nni_chunk_insert

    bug in nni_chunk_insert

    Describe the bug image image Like I paint in the second pic. If the ch_ptr = 2, ch_buf=0, ch_len=3, ch_cap=7, data len=4, the insert func will move ch_ptr to place 6 which is an error.

    Should correct memmove(ch->ch_ptr + len, ch->ch_ptr, ch->ch_len); to memmove(ch->ch_buf + len, ch->ch_ptr, ch->ch_len);

    opened by wutianze 0
  • Fix incorrect elides of deprecated code.

    Fix incorrect elides of deprecated code.

    (Note that this includes some incorrect formatting due to an apparent bug in clang-format 13. Hopefully they'll fix it later, but for now I'm preserving the bad whitespace.)

    fixes #

    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.

    opened by gdamore 1
  • Explore pthread_once and friends for initialization

    Explore pthread_once and friends for initialization

    We currently use our own locks, which are a bit dodgy, and possibly less efficient.

    We could conceivably use pthread_once or similar functions which should be highly optimized for the various platforms.

    Note that restarting after nng_fini might not be supported, or we might need to separate functions that perform once-ever initialization from those that might need to be called after finalization (e.g. for starting up worker threads after they have been shut down.)

    opened by gdamore 0
  • NNG_ELIDE_DEPRCATED spelling mistake and bug in initialization of dialer or listener

    NNG_ELIDE_DEPRCATED spelling mistake and bug in initialization of dialer or listener

    Describe the bug 1. Spelling mistake in src/core/socket.c line 1084: #ifndef NNG_ELIDE_DEPRCATED should be #ifndef NNG_ELIDE_DEPRECATED which will make this block of code be run all the time.

    src/core/socket.c line 597-605: When setting the default value of option nodelay and keepalive of dialer and listener in nni_sock_create, the dialer or listener list in the sock is empty, so the setting option seems to be meaningless. However, when creating a dialer or listener(ex. in posix_tcpdial.c), the default value of nodelay or keepalive is not set.

    opened by wutianze 0
  • mark deprecated functions as deprecated so they show as warnings during compile

    mark deprecated functions as deprecated so they show as warnings during compile

    defines a NNG_DEPRECATED macro that will emit the deprecated attribute supported by GCC & Clang Add this macro to all deprecated functions

    opened by urkle 5
  • Having deadlock in linux starting thread

    Having deadlock in linux starting thread

    Describe the bug The call to open the request socket gets stuck in a deadlock. The code is calling nng::req::open but it gets stuck in mutex deadlock

    Expected behavior The call should be opening the socket and not in deadlock

    Actual Behavior The stack trace is as follows: #0 0x00007f0e04d104ed in __lll_lock_wait () from /usr/lib64/libpthread.so.0 #1 0x00007f0e04d0bdcb in _L_lock_883 () from /usr/lib64/libpthread.so.0 #2 0x00007f0e04d0bc98 in pthread_mutex_lock () from /usr/lib64/libpthread.so.0 #3 0x00000000005447bd in nni_plat_init () #4 0x0000000000538cea in nni_init () #5 0x000000000053dbaf in nni_sock_open () #6 0x0000000000546ba2 in nni_proto_open () #7 0x0000000000546b7d in nng_req0_open ()

    It keeps waiting for the lock and doesn't open the socket

    To Reproduce This bug occurs sometimes, so no deterministic way to reproduce

    Environment Details

    • NNG version - Built using this commit db3d55 (Oct 27 2021)
    • Operating system and version - Centos 7, Kernel is 3.10.0-957.5.1.el7.x86_64
    • Compiler and language used - gcc 4.8
    • Shared or static library - static lib
    opened by sapgan 4
  • Performance of ipc/tcp in req/rep with single client/server

    Performance of ipc/tcp in req/rep with single client/server

    Hello! I have been starting to play with nng and I have a question about the performance of ipc vs tcp. 🙂

    Describe the question

    It is similar to the question that was asked in #1362 but while measuring the performance different between ipc vs tcp in the context of req/rep on a single client server.

    The setup is relatively simple: a client and server running on the same machine, the client sends a number of 128 byte messages to a server and the server returns the same messages. Testing this scenario with both tcp and icp.

    Here are the results:

    ===========================================================================================
    Benchmarking ipc - Data Size = 128
    ipc: 19525.846832071937 request_reply/s
    ipc: 51.214168 µs/request_reply
    ===========================================================================================
    Benchmarking tcp - Data Size = 128
    tcp: 22674.175476849814 request_reply/s
    tcp: 44.103037 µs/request_reply
    

    So, I'm curious about why ipc, which from what I understand in nng is relying on named pipes on Windows, seems to be 10% slower than the local tcp socket version. Any ideas? (It could be that I wrote something completely wrong, details at the bottom)

    ** Environment Details **

    • NNG version 1.5.2
    • Windows 11 x64 -
    • VS2019 x 64
    • Shared library

    Additional context

    Code details in C#

    I don't have a C program, but I wrote a C# program with my own raw wrapper of nng, which should look like very similar to a C version, it is a basic req/rep example with a loop around the receiv/send part

    using System.Diagnostics;
    using static nng;
    
    const int count = 100000;
    
    if (args.Length == 2)
    {
        switch (args[0])
        {
            case "--server":
                Server(args[1]);
                break;
        }
    }
    else
    {
        foreach (var size in new int[] { 128, 1024, 16384 })
        {
            Benchmark($"ipc:///tmp/SharpNngBenchmarks_{Guid.NewGuid():N}.ipc", size);
            Benchmark($"tcp://127.0.0.1:6001", size);
        }
    }
    
    static void Benchmark(string ipcName, int size)
    {
        var benchKind = ipcName.Substring(0, ipcName.IndexOf(':'));
        Console.WriteLine($"===========================================================================================");
        Console.WriteLine($"Benchmarking {benchKind} - Data Size = {size}");
    
        var process = new Process();
        process.StartInfo = new ProcessStartInfo(Process.GetCurrentProcess().MainModule.FileName, $"--server {ipcName}")
        {
            RedirectStandardError = true,
            RedirectStandardOutput = true,
            UseShellExecute = false,
            WindowStyle = ProcessWindowStyle.Hidden,
            CreateNoWindow = true
        };
    
        process.ErrorDataReceived += server_ErrorDataReceived;
        process.OutputDataReceived += server_OutputDataReceived;
        process.EnableRaisingEvents = true;
        process.Start();
        process.BeginOutputReadLine();
        process.BeginErrorReadLine();
    
        Thread.Sleep(1000);
        var clock = Stopwatch.StartNew();
        bool processTerminated = false;
        try
        {
            Client(ipcName, 128);
            clock.Stop();
            process.WaitForExit(1000);
            processTerminated = true;
            Console.WriteLine($"{benchKind}: {((double)count) / clock.Elapsed.TotalSeconds} request_reply/s");
            Console.WriteLine($"{benchKind}: {clock.Elapsed.TotalMilliseconds * 1000.0 / (double)count} μs/request_reply");
        }
        finally
        {
            if (!processTerminated)
            {
                process.Kill();
            }
        }
    }
    
    static void Server(string ipcName)
    {
        nng_socket sock = default;
    
        long sizeInBytesReceived = 0;
    
        int result = nng_rep0_open(ref sock);
        nng_assert(result);
        try
        {
            Console.Out.WriteLine($"Server: Starting {ipcName}");
    
            nng_listener listener = default;
            result = nng_listen(sock, ipcName, ref listener, 0);
            nng_assert(result);
    
            Console.Out.WriteLine("Server: Listening");
            for (int i = 0; i < count; i++)
            {
                // Receive the buffer
                result = nng_recv(sock, out var buffer);
                nng_assert(result);
                sizeInBytesReceived += buffer.Length;
                // Send the same buffer back
                result = nng_send(sock, buffer.AsSpan());
                nng_assert(result);
                buffer.Dispose();
            }
        }
        finally
        {
            nng_close(sock);
            Console.WriteLine($"Server: Closed ({sizeInBytesReceived} bytes received)");
        }
    };
    
    static void Client(string ipcName, int size)
    {
        Console.Out.WriteLine("Client: Started");
    
        nng_socket sock = default;
    
        int result = nng_req0_open(ref sock);
        nng_assert(result);
        var buffer = new byte[size];
    
        try
        {
            nng_dialer dialer = default;
            for (int i = 0; i < 10; i++)
            {
                result = nng_dial(sock, ipcName, ref dialer, 0);
                if (result == 0) break;
                Console.WriteLine("Client: dial failed, waiting for server to listen - sleep 100ms");
                Thread.Sleep(100);
            }
    
            nng_assert(result);
    
            Console.Out.WriteLine("Client: Connected");
            Console.Out.WriteLine("Client: Sending");
            for (int i = 0; i < count; i++)
            {
                result = nng_send(sock, buffer);
                nng_assert(result);
    
                result = nng_recv(sock, out var recvbuffer);
                nng_assert(result);
                if (recvbuffer.Length != buffer.Length) throw new InvalidOperationException("Size is not matching");
                recvbuffer.Dispose();
            }
        }
        finally
        {
            nng_close(sock);
            Console.WriteLine("Client: Closed");
        }
    };
    
    
    static void server_ErrorDataReceived(object sender, DataReceivedEventArgs e)
    {
        if (e.Data == null) return;
        Console.WriteLine(e.Data);
    }
    
    static void server_OutputDataReceived(object sender, DataReceivedEventArgs e)
    {
        if (e.Data == null) return;
        Console.WriteLine(e.Data);
    }
    
    opened by xoofx 5
  • two nodes dial one node when using pair protocol doesn't return error

    two nodes dial one node when using pair protocol doesn't return error

    Describe the bug When using pair protocol(version 0 or version 1), I try to use more than one node to dial one node. Let's say node1 and node2 try to talk with node0 at the same time. The result is node0 and node1 can talk freely, but node2 can still run nng_dial or nng_send without returning error, although node0 seems to ignore the msg from node0.

    Expected behavior When node0 and node1 make a pair, node2 should fail to build another one-to-one relationship with node0 which means nng_dial or nng_send by node2 shouldn't return 0.

    Actual Behavior nng_send and nng_dial by node2 still return 0.

    To Reproduce Use the pair demo in the getstarted doc: https://nanomsg.org/gettingstarted/nng/pair.html. Just add one node.

    ** Environment Details **

    • NNG version: latest
    • Operating system and version: ubuntu 20.04
    • Compiler and language used: c
    • Shared or static library
    opened by wutianze 4
  • C/C++ executable is SEGVing sporadically in `nni_list_remove`.

    C/C++ executable is SEGVing sporadically in `nni_list_remove`.

    Description

    This is not currently very actionable by nng devs as I cannot present a simple way to reproduce it. But I'm reporting it in case someone can offer any helpful insight as I continue to try to track it down.

    I'm using direct C bindings for nng 1.5.2, straightforward modest use of PUB/SUB only so far. Sadly it's something of a Heisenbug, as instrumenting the code reduces its frequency.

    Here are two SEGV stack traces I've observed:

    #0  0x0000005572ba6240 in nni_list_remove ()
    #1  0x0000005572bb6400 in sub0_recv_cb ()
    #2  0x0000005572bb0584 in nni_task_exec ()
    #3  0x0000005572ba2da0 in nni_aio_finish_impl ()
    #4  0x0000005572ba2e20 in nni_aio_finish_sync ()
    #5  0x0000005572bb8b10 in ipc_pipe_recv_cb ()
    #6  0x0000005572bb0114 in nni_taskq_thread ()
    #7  0x0000005572bb0b40 in nni_thr_wrap ()
    #8  0x0000005572bb41bc in nni_plat_thr_main ()
    #9  0x0000007f88277088 in start_thread (arg=0x7fd0cde9df) at pthread_create.c:463
    #10 0x0000007f87e64ffc in thread_start () at ../sysdeps/unix/sysv/linux/aarch64/clone.S:78
    
    #0  0x0000005570b752d0 in nni_list_remove ()
    #1  0x0000005570b836c4 in sub0_ctx_cancel ()
    #2  0x0000005570b721d8 in nni_aio_expire_loop ()
    #3  0x0000005570b7e994 in nni_thr_wrap ()
    #4  0x0000005570b81e1c in nni_plat_thr_main ()
    #5  0x0000007f790d8088 in start_thread (arg=0x7fe75ba76f) at pthread_create.c:463
    #6  0x0000007f78cc5ffc in thread_start () at ../sysdeps/unix/sysv/linux/aarch64/clone.S:78
    

    Since I found no other reports mentioning nni_list_remove, I initially suspected it could be issues outside nng, e.g. other code tramping over memory, so I ran under valgrind with our code compiled DEBUG, and found no problems, though the frequency of crashes reduced running our the DEBUG built code.

    I have now built nng itself DEBUG, so far no crashes, but execution time has been limited so far.

    I only get crashes on our build on our target NVidia Jetson Nano board ARMv8 Processor rev 1 (v8l), not when running on a X86. This is a low powered, ballpark of Raspberry Pi.

    The user of the sub channels is a thread in a while loop receiving messages, and the socket is configured with NNG_OPT_RECVTIMEO at 500.

    Environment Details

    static nng 1.5.2 (also tried 1.4.0, got same crash) gcc 9.4 Ubuntu 18.04 NVidia Jetson Nano board 4 core ARMv8 Processor rev 1 (v8l). Not observed on X86, but code is exercised less there, so could be chance.

    opened by WJCFerguson 3
  • tests/httpserver static handler response body format not correct

    tests/httpserver static handler response body format not correct

    Describe the bug

    1. add test code nng_msleep(3600000) at line 284 tests/httpserver, then build and run httpserver
    2. postman send GET http://127.0.0.1:5547/home.html
    3. response ERROR body: <html><body>Someone <b>is</b> home!</body</html>
    4. expected correct body: <html><body>Someone <b>is</b> home!</body></html>

    Expected behavior Except body: <html><body>Someone <b>is</b> home!</body></html>

    Actual Behavior Actual body: <html><body>Someone <b>is</b> home!</body</html> lost '>' behind "</body"

    To Reproduce Non

    ** Environment Details **

    • NNG version: v1.5.1
    • Operating system and version: Ubuntu 20.04
    • Compiler and language used: gcc9.0
    • Shared or static library: static library

    Additional context Non

    opened by ZRiemann 0
Releases(v1.5.2)
  • v1.5.2(Aug 11, 2021)

    This release addresses a number of issues with 1.5.1 and 1.5.0, and users of those versions are encouraged to upgrade.

    • MbedTLS 3.0 is now supported
    • Several bugs in the aio subsystem leading to hangs or performance issues are addressed
    • Possible crash due to mismatched nni_strdup/free usage fixed
    • Fix for building on iOS, tvOS, iPadOS, watchOS
    • Incorrect version number macros in CMake configuration fixed
    • Several other minor cleanups (remove dead code, simplify some things)
    Source code(tar.gz)
    Source code(zip)
  • v1.5.1(Jul 11, 2021)

  • v1.5.0(Jul 10, 2021)

    This release provides a two new convenience APIs, nng_msg_reserve() and nng_msg_capacity(), which can help with avoiding preallocations.

    Additionally this release fixes a bug introduced in v1.4.0 where setting IPC socket permissions on Linux did not work.

    Source code(tar.gz)
    Source code(zip)
  • v1.4.0(Feb 8, 2021)

    This is principally a performance release, as we have introduced a bunch of new features that should improve performance, especially for higher end systems (those with multiple cores will see substantially improved scalability, and lower latencies.)

    Other features:

    • TCP ports may now be specified as service names.
    • wss4, wss6, ws4, and ws6 can be used to force IPv6 or IPv4 binding for websocket URLs.
    • REQ will fail fast if no retry timer is present, and the peer disconnects
    • abstract sockets can be used on Linux (see nng_ipc.7 for details)
    • websocket stream mode now supports TEXT mode streams
    • thread names can be set, and NNG will set names for its own (see nng_thr_setname.3)
    • IPv6 scoped addresses are supported
    • nngcat grew --file and --data options to supply data to send

    Thanks.

    Source code(tar.gz)
    Source code(zip)
  • v1.3.2(Aug 2, 2020)

    This release is just a set of improvements to fix some documentation bugs. These fixes are necessary for some of the automatic tooling we use for publication of documentation.

    If already running v1.3.1, there is no urgency to update.

    Source code(tar.gz)
    Source code(zip)
  • v1.3.1(Jul 28, 2020)

    This is a bug fix release that rolls up a bunch of bug fixes.

    • WebSocket and HTTP support for IPv6 addresses (note: IPv6 scopes are still not supported) (#844, #1224)
    • Build fixes for NetBSD, OpenBSD, and Android (#1232, #1237)
    • Serious framing error in TLS (regression introduced in 1.3.0) (#1235)
    • nng_msg_clear was clearing the header; now it only clears the body (#1252)
    • Use-after-free segfault in rep protocol (#1241)
    • NNG_OPT_RECONNMAXT zero did not prevent exponential backoff (#1230)
    • Use-after-free in TLS (#1239)
    • Hangs in nng_close fixed (#1236, #1219)
    • Fixes to ease inclusion in other projects
    • Numerous minor doc bugs fixed
    • Various test suite bugs fixed

    Also there are two minor feature enhancements:

    • Support for obtaining the peer process ID using IPC on modern macOS
    • nngcat now supports data from standard input when the file is specified as "-" (#1007)

    It is recommended that all users using v1.3.0 upgrade to v1.3.1.

    Source code(tar.gz)
    Source code(zip)
  • v1.3.0(Mar 1, 2020)

    Features

    • Support for TLS 1.3 and external TLS providers. There is now an API whereby external "engines" can be developed for different TLS implementations. The first of these, for wolfSSL, is available. Set this with the NNG_TLS_ENGINE cmake option. The default is still to use Mbed TLS. The wolfSSL plugin is available under a different license (GPLv3 or commercial), and also provides support for TLS 1.3 and FIPS 140-2 capable solutions.

    • Message cloning and related performance improvements. This is not a feature, so much as a rather large improvement in terms of performance. All workloads will see some benefit -- some will see substantial benefits.

    • Numerous other performance improvements. Much effort was made to reducing allocations, improving cache effectiveness, and eliminating extra context switches. This work is not yet done, but this is a big step in the right direction.

    • HTTP Server support for "non-exclusive" registration -- a given handler may be registered as a fallback handler (e.g. for a directory), even if more specific handlers are registered.

    • Performance test programs grew more options to select different protocols and to change the URL to test across different transports.

    Notable Bug Fixes

    • Thread count is limited. Previously we would spawn potentially vast numbers of threads based on the number of available cores. By default we set an upper limit on this that is about 20 threads. Tune this with the NNG_MAX_TASKQ_WORKERS cmake option.

    • Raw mode fixes for XREQ and XRESPONDENT. These protocols used the raw mode inconsistently, leaving the header in the message body. This is corrected and the protocol headers are kept in the message headers. There is some small risk that some applications broken, but we are not aware of any that used RAW mode to parse message headers.

    • HTTP Server root URL handling had a few issues which are resolved.

    • Some platforms had difficult building due to inconsistencies in the handling of atomics.

    • Numerous test suites uncovered small (rare) races, etc. The tests themselves were often racy. Fixes to both NNG and the tests have been made, while increasing overall test coverage.

    • REP protocol with SENDFD was inconsistent (#1088).

    Other Changes

    • Polyamorous Pair v1 mode is changed, such that a new API call is needed to use it. Further, this mode will likely be removed in a future release. Note that this mode also does not work with other implementations, nor does it support operation with nng_device().

    • Maximum hop count across nng_device() proxies is now limited to 15. This limit should be sufficient for all reasonable configurations, and forcing this allowed us to to inline the header for performance reasons.

    • The nng_msg_options support was removed. It was not used for anything.

    Source code(tar.gz)
    Source code(zip)
  • v1.2.6(Feb 6, 2020)

    This is another release to fix builds for older compiles without support for C11 atomics.

    If you were able to build prior releases, there is no need to update to this release. Generally speaking, the use of older compilers will give less than ideal results; if at all possible upgrading to modern compilers is strongly recommended. The performance different is likely to be significant.

    Source code(tar.gz)
    Source code(zip)
  • v1.2.5(Jan 27, 2020)

    This release fixes a mistake that prevented the code from building for people on older compilers or older operating systems. Users of v1.2.4 do not need to upgrade.

    Source code(tar.gz)
    Source code(zip)
  • v1.2.4(Jan 13, 2020)

    This fix contains an URGENT bug fix, and all users using v1.2.x where x <= 3 should upgrade at their earliest opportunity.

    The bugs fixed are:

    • #1132 Masking error in LMQ leads to corruption
    • #1131 (openindiana) compile error
    • fix reported versions in nng.h and CMakeLists.txt

    The critical bug here is #1132 which leads to use after free heap corruption, and unpredictable results once the receive or send queue wraps. The other two bugs are less critical, but should help Solaris and illumos users, and correct a bug where we reported wrong the ABI version (which could cause compatibility problems when mixing older versions with v1.2.x.)

    Source code(tar.gz)
    Source code(zip)
  • v1.2.3(Dec 31, 2019)

    This release fixes a number of important bugs. It's highly recommended that folks using v1.2.0, v1.2.1, or v1.2.2 upgrade to this release.

    Specifically fixed:

    • #1079 Use after free in tcp dialer
    • #1075 WebSocket use after free
    • #1064 Potential deadlock in statistics code
    • #1065 resolver leaks work structures

    There were also several fixes to the test suite included with these changes.

    Source code(tar.gz)
    Source code(zip)
  • v1.2.2(Dec 28, 2019)

    This release fixes two bugs that were affecting some people:

    • Crashes in the websocket code. (#986) Folks using the websocket transport are highly encouraged to update. This bug could have led to either application crashes or data corruption in transit.

    • Windows client connections not supporting NNG_OPT_LOCADDR (#1062)

    This release also includes changes to the way tests are created and managed, so that more tests are run, they are easier to write, easier to collect coverage for, and easier to diagnose when they fail. This won't impact built libraries, but it should have a big improvement on the overall quality of the library over time. This will be an ongoing work.

    We're also making better use of GitHub actions to test on more systems, and more configurations. While this has helped to uncover some real bugs in the library, it has also started uncovering brittleness in the test suites themselves. This is the source of a lot of false failures; we will continue working on this going forward.

    Source code(tar.gz)
    Source code(zip)
  • v1.2.1(Dec 24, 2019)

    Version 1.2.1 is mainly being released to correct a problem with the semantic versioning in the shared library interfaces. It also corrects a problem that may have affect non-mainstream platforms, without support for atomic operations.

    Other changes should not affect library users.

    Source code(tar.gz)
    Source code(zip)
  • v1.2.0(Dec 22, 2019)

    Version 1.2 is a minor feature release of NNG.

    • Notably it includes support for non-SP protocol usages -- for example NNG can be used to make generic websocket or HTTP applications now.
    • The default maximum receive size is lifted. (If you use NNG on an untrusted network, please set an explicit limit instead of relying on the defaults!)
    • Substantial work on performance. Most protocols should see a nice boost.
    • Numerous bugs fixed.

    Hopefully the next release won't be so far in the future. Thanks to everyone for their patience.

    Source code(tar.gz)
    Source code(zip)
  • v1.1.1(Nov 22, 2018)

    Version 1.1.1 patch release.

    This fixes a few problems with 1.1.0.

    • The version number at build time was misreported as 1.0.1. It will now be 1.1.1.
    • Support for use in CMake scenarios involving add_subdirectory
    • Fix for the bug report URL if NNG crashes
    • Fix for a crash if a remote websocket peer sends PING requests
    Source code(tar.gz)
    Source code(zip)
  • v1.1.0(Nov 10, 2018)

    There are numerous bug fixes and improvements in this since 1.0.1.

    DNS resolution is done asynchronously at dial time, leading to better self healing in the face of changing DNS records (and the possibility to use DNS for round-robin load balancing.)

    Better peer identification is possible with IPC based transports.

    The HTTP framework has better support for cancellation, and the HTTP client has a much friendlier ability to execute transactions. Additionally, the HTTP client can now support servers that insist on sending chunked transfer encodings.

    The ZeroTier transport received a lot of work, so that it is far more stable, and supports more properties relating to peer identification. There are (undocumented) options to tune the local IP addresses used in ZeroTier as well. Also, the entire configuration process for ZeroTier is much saner.

    A statistics API is available to obtain statistics about the application. Unfortunately, only a few statistics have been added -- more will be added in coming releases.

    More modern CMake style is used to provide much more correct use from CMake projects - it should no longer be necessary to call find_package(Threads) or similar.

    Better support for more platforms (older versions of Linux, Alpine Linux, QNX).

    A variety of stability fixes and performance improvements.

    A number of documentation improvements and corrections have been made as well.

    Source code(tar.gz)
    Source code(zip)
  • v1.1.0-rc(Nov 6, 2018)

    This is a release candidate for 1.1.0.

    There are numerous bug fixes and improvements in this since 1.0.1.

    DNS resolution is done asynchronously at dial time, leading to better self healing in the face of changing DNS records (and the possibility to use DNS for round-robin load balancing.)

    Better peer identification is possible with IPC based transports.

    The HTTP framework has better support for cancellation, and the HTTP client has a much friendlier ability to execute transactions. Additionally, the HTTP client can now support servers that insist on sending chunked transfer encodings.

    The ZeroTier transport received a lot of work, so that it is far more stable, and supports more properties relating to peer identification. There are (undocumented) options to tune the local IP addresses used in ZeroTier as well. Also, the entire configuration process for ZeroTier is much saner.

    A statistics API is available to obtain statistics about the application. Unfortunately, only a few statistics have been added -- more will be added in coming releases.

    More modern CMake style is used to provide much more correct use from CMake projects - it should no longer be necessary to call find_package(Threads) or similar.

    A number of documentation improvements have been made as well.

    Source code(tar.gz)
    Source code(zip)
  • v1.0.1(Jul 5, 2018)

    This is a bug fix release, and contains fixes for several important bugs. Users of macOS and BSD operating systems should see a huge reduction in CPU overhead as a critical kqueue processing bug is fixed. The IPC transport also got a critical fix to eliminate accidental deletion of the socket incorrectly.

    There is one feature that snuck in (my bad!) which is that it is now possible to customize the HTTP error page -- see nng_http_server_set_error_file() or nng_http_server_set_error_page() for details.

    A few other minor bugs were fixed as well, including a leak in the URL, an inability to tune dialer reconnection timers individually.

    More stabilization work and feature work is pending, but these issues are important enough that we felt it worthwhile to push this release out while we finish up the work on the other issues.

    Source code(tar.gz)
    Source code(zip)
  • v1.0.0(Jun 8, 2018)

    This is the first "stable" release of NNG. While there are many more things to do in NNG, we are recommending users being transitioning to NNG away from nanomsg.

    Source code(tar.gz)
    Source code(zip)
  • v1.0.0-rc.1(Jun 2, 2018)

    This is a release candidate. At this point we consider ourselves ready for 1.0.0 final release. This does have some changes in it, so we will wait a little bit before the final release:

    Changes since beta.2:

    • Honors BUILD_SHARED_LIBS CMake setting (see below)
    • Support for Android added
    • Instructions for building with Xcode for iOS (no code changes were needed)
    • Support for enabling sanitizers (address, thread, memory, undefined) via NNG_SANITIZER
    • Fixes for bugs found with sanitizers (use-after-free, leaks)
    • Simplified synchronization primitives on POSIX (no fallback needed)
    • CMake exported target (easier integration within CMake projects) & demos
    • Shared library symbol visibility is reduced by default
    • Documentation updates (various) found during editing

    Essentially this project should be easier to use, provided you have a sane CMake installation. It attempts to be a well-behaved citizen in CMake-land, so should be easier to nest into other projects.

    The one very important change is that we use the platform-specific defaults to decide whether to build shared or static libraries, and only build either shared or static -- not both. The determination of which to build is driven by the BUILD_SHARED_LIBS macro, which is user-accessible via CMake. This is more closely aligned with usual CMake practice.

    Also, if you were using our library to access private symbols, that is a no-no, and may not work anymore, as the shared library is now more careful to only export the symbols we have intended for external use. (Build and use a static library if you need to work around that, but you really should only be using the public symbols.) This was already the default behavior for Windows.

    Source code(tar.gz)
    Source code(zip)
  • v1.0.0-beta.2(May 22, 2018)

    This is the second beta release of NNG 1.0.0.

    NNG is now on a functional code freeze. Furthermore, the ABI is now frozen (library version 1.0.0).

    We will very carefully evaluate any new bugs found before this is released for GA; only severe bugs will be considered for integration at this time. If such a bug is found and a fix is required, we will release another beta release.

    Permitted changes include test programs, demonstration programs, and documentation fixes and improvements. Also, minor changes to improve the release process, packaging, and non-runtime aspects of the library may be permitted, subject to review.

    We expect to release one more change, which will be a release candidate (RC1) before final release. More details about release plans will be posted to the mailing list.

    What's changed since 1.0.0-beta.1?

    • Library ABI is now 1.0.0
    • Websocket transport now honors NNG_OPT_RECVMAXSIZE
    • Legacy mode headers are now more compatible with legacy nanomsg
    • SUB protocol is more aggressive at dropping undeliverable messages
    • Compat mode supports NN_TCP_NODELAY
    • NNG_OPT_TCPNODELAY and NNG_OPT_KEEPALIVE defaults are set at socket creation
    • Bug fix in the websocket URL parsing (if no path is given to websocket URL)
    • SO_REUSEADDR is now set on listening TCP sockets on POSIX systems
    • Various improvements and corrections to documentation

    Thanks for your continued testing and support!

    Source code(tar.gz)
    Source code(zip)
  • v1.0.0-beta.1(May 18, 2018)

    Good news! NNG 1.0.0 has reached development complete, and is now entering its first beta period.

    During this beta period, no new features will be introduced into the this release. Furthermore, changes to the functional code of the library itself will be restricted to bug fixes. Any bugs requiring non-trivial changes to the library will necessitate another beta cycle before entering the release candidate phase.

    Permitted changes include test programs, demonstration programs, and documentation fixes and improvements. Also, some changes to improve the release process, packaging, and non-runtime aspects of the library are permissible.

    What's new since 0.9.0?

    • NNG_TCP_OPT_NODELAY option (and legacy compat)
    • Socket, pipe, and similar types are now structural instead of integers
    • Pipe notification callbacks. See nng_pipe_notify(3) for details.
    • Peer identification option for IPC transport (see nng_ipc(7) for details.)
    • Solaris and illumos support, including scalable port event based poller.
    • New options to nngcat(1) to control repeat count and message size.
    • Significant changes that should reduce lock contention and increase performance and scalability.
    • New tcp4://, tcp6://, tls+tcp4://, and tls+tcp6:// scheme support. See nng_tcp(7) and nng_tls(7).

    Numerous bugs have been fixed, supported by much more extensive testing and significant improvements to the test suite itself.

    Thank you for helping us ensure the highest quality release by testing this out!

    Source code(tar.gz)
    Source code(zip)
  • 0.9.0(Apr 25, 2018)

    The big change for this release is context support used for REQ/REP to SURVEYOR/RESPONDENT. With this change, there is very little reason for raw sockets to be used, except in creation of devices and obscure test and debug scenarios.

    A few bugs, some serious, have been fixed -- most notably a serious regression in REQ/REP caused by the original context work -- this turned out to have sweeping ramifications, and small changes were made across the code base to resolve the key issue (which was the need to separate nni_aio_start into two separate functions, which are now nni_aio_begin and nni_aio_schedule. Note that these two functions are for internal use only.)

    Additionally, the compatible API is now documented.

    At this point we consider nng "feature complete" for a 1.0 release; we will be focusing on performance, bugs, test cases, and demonstration code for the rest of the lead-up to 1.0. (We do have post-1.0 features planned, of course!)

    Note that there are still some edge case features missing from nng which are present in nanomsg -- statistics, pipe priorities, certain socket options (TCP_NODELAY for example), and security attributes (named pipes on Windows only). We may still add support for some of these missing things before 1.0 depending on risk assessment. Otherwise we will do them in the following release. (If any of these features are a stopper for you, and you are using them with nanomsg, please let us know!)

    Source code(tar.gz)
    Source code(zip)
  • 0.8.0(Apr 12, 2018)

    This release has what should be the final breaking API changes prior to 1.0. Specifically, the RAW mode sockets are no longer established by NNG_OPT_RAW -- which has become a read-only option, but are instead created by new constructors, such as nng_req0_open_raw().

    Additionally, this release introduces a major new capability -- contexts. The details of this are located in the nng_ctx(5) manual page, as well as an example. An example showing the use of contexts with the HTTP server API to create a REST API to REQ/REP gateway exists in the demo/rest directory. At the moment contexts are only available for REQ and REP protocols -- addition of support for contexts with SURVEYOR and RESPONDENT is planned for the next release.

    Note that users of the REQ and REP protocols may notice differences in behavior around queueing and flow control -- in particular REQ will probably apply backpressure now, so that attempts to send requests will block if there are no pipes available (and the pollable status will reflect this.)

    Significant performance improvements have been made -- users may see up to 20% better performance compared to 0.7.0, depending on numerous factors. More work in this area is still planned.

    A number of other issues (bugs) have been fixed as well.

    We would be especially grateful for any extra testing, especially of the REQ and REP protocols and the new context facility.

    Source code(tar.gz)
    Source code(zip)
  • 0.7.0(Mar 19, 2018)

    This release has some breaking changes for users of properties such as NNG_OPT_RAW and NNG_OPT_PAIR1_POLY, as well as users of the ZeroTier transport.

    Most of the other changes in this release amount to massive documentation improvements.

    However, Linux now uses epoll(), thanks to a contribution by Liam Staskawicz, which should lead to greater scalability.

    There is a new nng_sleep_aio() API, and a demo/async program that demonstrates using the async AIO features.

    Please also note that the documentation on the website and on Leanpub has all been updated to reflect this.

    We are getting much closer to a 1.0 release, so I'm really grateful for testing and review feedback!

    Thanks!

    Source code(tar.gz)
    Source code(zip)
  • 0.6.0(Mar 11, 2018)

    This release involves primarily bug fixes for the ZeroTier transport, and documentation updates.

    Applications using the ZeroTier transport option NNG_ZT_NETWORK_STATUS should be aware that this option has changed; code updates will be required. See the nng_zerotier(7) man page for more details.

    Source code(tar.gz)
    Source code(zip)
  • 0.5.0(Mar 2, 2018)

    This release adds the following:

    • nngcat utility
    • many manual pages
    • kqueue based BSD poller (performance & scalability)
    • public HTTP API
    • Improvements to the TLS API
    • Numerous bug fixes

    We believe this release is getting reasonably close to being ready to stabilize for a public API.

    Testing and review is requested!

    Source code(tar.gz)
    Source code(zip)
  • 0.2.0(Dec 31, 2017)

    This version adds quite a lot since 0.1.0, but most notable is the addition of websocket (ws://) and websocket secure (wss://) support.

    Please be careful and don't use this in production yet, but it is suitable for development and testing. There might still be API breakage in the future, but things are looking more and more stable now.

    Source code(tar.gz)
    Source code(zip)
  • 0.1(Nov 21, 2017)

    This is the first "pre-release" of nng. A lot may still change (even the project name!), but most of the core functionality is now working well enough for us to post this for users to test against.

    Please note that 0.1 means what it says -- you should not depend on this for anything, and we will probably break things in future releases -- there are no semantic version guarantees here.

    Source code(tar.gz)
    Source code(zip)
Owner
nanomsg
Nanomsg Project
nanomsg
Harsh Badwaik 1 Oct 21, 2021
zlib replacement with optimizations for "next generation" systems.

zlib-ng zlib data compression library for the next generation systems Maintained by Hans Kristian Rosbach aka Dead2 (zlib-ng àt circlestorm dót org) C

zlib-ng 4 Nov 19, 2021
zlib replacement with optimizations for "next generation" systems.

zlib-ng zlib data compression library for the next generation systems Maintained by Hans Kristian Rosbach aka Dead2 (zlib-ng àt circlestorm dót org) C

zlib-ng 4 Nov 19, 2021
zlib replacement with optimizations for "next generation" systems.

zlib-ng zlib data compression library for the next generation systems Maintained by Hans Kristian Rosbach aka Dead2 (zlib-ng àt circlestorm dót org) C

zlib-ng 969 Dec 4, 2021
This repository accompanies Ray Tracing Gems II: Next Generation Rendering with DXR, Vulkan, and OptiX

Apress Source Code This repository accompanies Ray Tracing Gems II: Next Generation Rendering with DXR, Vulkan, and OptiX by Adam Marrs, Peter Shirley

Apress 577 Dec 5, 2021
FluidNC - The next generation of motion control firmware

FluidNC (CNC Controller) For ESP32 Introduction FluidNC is the next generation of Grbl_ESP32. It has a lot of improvements over Grbl_ESP32 as listed b

null 112 Nov 29, 2021
A next generation media player, with vim-like bindings

MusicKid A next generation media player, with vim-like bindings Installation Clone the repo git clone <git-url> cd MusicKid/Final Install dependencies

null 2 Sep 22, 2021
pugixml is a Light-weight, simple and fast XML parser for C++ with XPath support

pugixml is a C++ XML processing library, which consists of a DOM-like interface with rich traversal/modification capabilities, an extremely fast XML parser which constructs the DOM tree from an XML file/buffer, and an XPath 1.0 implementation for complex data-driven tree queries. Full Unicode support is also available, with Unicode interface variants and conversions between different Unicode encodings (which happen automatically during parsing/saving).

Arseny Kapoulkine 2.8k Dec 6, 2021
Poseidon OS (POS) is a light-weight storage OS

Poseidon OS Poseidon OS (POS) is a light-weight storage OS that offers the best performance and valuable features over storage network. POS exploits t

null 32 Nov 29, 2021
A light-weight Flutter Engine Embedder based on HADK ,which for Android devices that runs without any java code

flutter-hadk A light-weight Flutter Engine Embedder based on HADK ,which for Android devices that runs without any java code 1.Build by android-ndk-to

null 13 Nov 8, 2021
Light-weight UNIX backdoor

JadedWraith Lightweight UNIX backdoor for ethical hacking. Useful for red team engagements and CTFs. Something I wrote a few years ago as part of a ga

null 112 Nov 29, 2021
Analytics In Real-time (AIR) is a light-weight system profiling tool

Analytics In Real-time Analytics In Real-time (AIR) is a light-weight system profiling tool that provides a set of APIs for profiling performance, lat

null 3 Nov 29, 2021
Ducktape is an Open source Light weight 2d Game Engine that gives utmost priority to user convenience.

Ducktape is an Open source Light weight 2d Game Engine that gives utmost priority to user convenience. It is written in c++ and uses SFML and Box2d for graphics and physics respectively.

Ducktape 19 Dec 6, 2021
qpSWIFT is a light-weight sparse quadratic programming solver

qpSWIFT Light-weight sparse Quadratic Programming Solver Introduction qpSWIFT is light-weight sparse Quadratic Programming solver targetted for embedd

qpSWIFT 22 Nov 26, 2021
A light-weight music Discord bot using Orca.

What's the "Music Discord bot with C"? A light-weight music Discord bot using Orca for it's bot. It's easy to use and install. How to download and use

ThePedro 6 Nov 12, 2021
A very simple and light-weight drawing app made with qt and C++.

Blackboard A very simple and light-weight drawing app made with qt and C++. It supports tablet and pen pressure with the help of QTabletEvents. So you

null 1 Nov 15, 2021
Fast and Light-weight path smoothing methods for vehicles

path_smoother About Fast and Light-weight path smoothing methods for vehicles Denpendencies This project has been tested on Ubuntu 18.04. sudo apt-get

MingwangZhao 4 Dec 1, 2021
nanomsg library

Welcome to nanomsg The nanomsg library is a simple high-performance implementation of several "scalability protocols". These scalability protocols are

nanomsg 5.3k Dec 1, 2021
nanomsg library

Welcome to nanomsg The nanomsg library is a simple high-performance implementation of several "scalability protocols". These scalability protocols are

nanomsg 5.3k Dec 4, 2021
Decoding light morse code with a light dependent resistor and Arduino board

Morse decoder The project's idea is very simple, the Arduino program has the responsibility to upload the sensor's data to the USB serial port.

null 13 Oct 5, 2021
Easy to use cryptographic framework for data protection: secure messaging with forward secrecy and secure data storage. Has unified APIs across 14 platforms.

Themis provides strong, usable cryptography for busy people General purpose cryptographic library for storage and messaging for iOS (Swift, Obj-C), An

Cossack Labs 1.4k Dec 3, 2021
null 162 Dec 2, 2021
Flutter-v2 Firebase Messaging, Foreground and Background Notifications + Topic Subscription and Broadcast Notifications Source code

Flutter Notification & FCM The repo is about flutter notification and FCM (Firebase Cloud Messaging). It is updated with Flutter v2 and new updates of

Amanullah 23 Nov 25, 2021
Messaging Client - Server application

Message_Client-Server Messaging Client - Server application Message Socket Server (server.c) Uses TCP/IP (stream socket) Requieres: 1 command paramete

George 2 Oct 5, 2021
Introduction to AWS IoT Core and a Post Messaging demo

IoT_Message_Box_Workshop Introduction to programming microcontrollers for IoT applications and interfacing them with AWS IoT Core This workshop was pr

Raw Matter 5 Dec 1, 2021
A Keg tracking system that monitors weight

KegScale A Keg tracking system that monitors weight Right now the arduino zeros the scale when it turns on and subracts the weight of 5 gallon corny k

null 10 Aug 27, 2021
An intrusive C++17 implementation of a Red-Black-Tree, a Weight Balanced Tree, a Dynamic Segment Tree and much more!

This is Ygg (short for Yggdrasil), a C++17 implementation of several intrusive data structures: several balanced binary search trees: a red-black Tree

Lukas Barth 90 Oct 22, 2021