A packet acknowledgement system for UDP

Overview

Build status

Introduction

reliable is a simple packet acknowledgement system for UDP-based protocols.

It has the following features:

  1. Acknowledgement when packets are received
  2. Packet fragmentation and reassembly
  3. RTT and packet loss estimates

reliable is stable and production ready.

Author

The author of this library is Glenn Fiedler.

Open source libraries by the same author include: netcode and yojimbo

Glenn is now the founder and CEO of Network Next. Network Next is a new internet where networks compete on performance and price to carry your traffic. Check it out at https://networknext.com

Source Code

This repository holds the reference implementation of reliable in C.

Other reliable implementations include:

Contributors

These people are awesome:

Sponsors

reliable was generously sponsored by:

And by individual supporters on Patreon. Thank you. You made this possible!

License

BSD 3-Clause license.

Comments
  • why isn't there an acked_packet_function callback?

    why isn't there an acked_packet_function callback?

    I see 2 callback functions defined:

    void (*transmit_packet_function)(void*,int,uint16_t,uint8_t*,int); is fired whenever a packet is ready to be sent. it's implementation should handle actually sending data over the socket.

    int (*process_packet_function)(void*,int,uint16_t,uint8_t*,int); is fired whenever a packet is received (either a regular packet or a fragmented packet that's been fully re-assembled)

    I'm surprised that there is no callback function that is invoked whenever a packet goes from non-acked -> acked. Isn't this the kind of callback one would need to build a reliable message system on top of reliable.io ? Otherwise you'd have to duplicate all of https://github.com/networkprotocol/reliable.io/blob/master/reliable.c#L1090-L1120 logic inside your process_packet_function. Or is there a better way to handle this?

    opened by mreinstein 7
  • should process_packet_function receive the endpoint in its parameters?

    should process_packet_function receive the endpoint in its parameters?

    Not an issue but more of a philosophical question.

    When processing a packet, it would be a normal operation to reply on the same endpoint using reliable_endpoint_send_packet. As of now we receive a <context,index> pair (btw, not sure what is the index utility).

    opened by aghiles 6
  • Need hints on how to handle packet re-transmission.

    Need hints on how to handle packet re-transmission.

    Reading the docs and the code (no comments!), I am not sure how to proceed. So I am sending a packet over UDP using a reliable "endpoint". Does reliable.io handles re-transmission, I see that reliable_endpoint_receive_packet does some ACK computations but never writes back to sending endpoint. I think a step-by-step explanation would do wonder for this little library.

    opened by aghiles 6
  • questions on reliable_endpoint_t structure

    questions on reliable_endpoint_t structure

    while looking at:

    struct reliable_endpoint_t
    {
       .
       .
       .
        uint16_t * acks;
        uint16_t sequence;
        struct reliable_sequence_buffer_t * sent_packets;
        struct reliable_sequence_buffer_t * received_packets;
    

    I don't understand the usage sequence and sent_packets as used on these lines:

    https://github.com/networkprotocol/reliable.io/blob/master/reliable.c#L725 https://github.com/networkprotocol/reliable.io/blob/master/reliable.c#L733

    Is this redundant? Why effectively store 3 sequence numbers when the 2 above lines seem to conflate sequence with sent_packets->sequence ?

    opened by mreinstein 6
  • documentation/logic questions

    documentation/logic questions

    @gafferongames in working on a javascript port, I was going through the code in this library. It's so well written that I could follow along very easily. Very refreshing!

    There are 3 areas where there is a little head scratching:

    I suspect this code has to do with handling very rare cases of extreme packet loss with sequence buffer wrap around: https://github.com/networkprotocol/reliable.io/blob/master/reliable.c#L249-L256

    similarly, there's some logic in `_remove_entries which is a little confusing: https://github.com/networkprotocol/reliable.io/blob/master/reliable.c#L207-L226

    It's not clear to me what the _with_cleanup variants of sequence buffer insertion/removal are for https://github.com/networkprotocol/reliable.io/blob/master/reliable.c#L264 https://github.com/networkprotocol/reliable.io/blob/master/reliable.c#L264

    I think comments in here about what these little bits are would be immensely helpful. Everything else makes total sense.

    Thanks again for a great codebase!

    opened by mreinstein 5
  • [Question] How retransmits are handled?

    [Question] How retransmits are handled?

    Hi Glenn!

    I read source, and I can't get the way retransmits are handled. Let's say we have next situation. A send to B single packet, which is dropped during transmission. A -[DATA1]-XXXXX (missing)-> B Because B miss this packet, it will never send ACK to A (or any other thing).

    How A should resolve this situation? Likely there should be some timer, which should retransmit non-ACKed packets after some time. Like (simplified):

    while (reliable_endpoint_pending(endpoint)) {
       sleep(reliable_endpoint_wait_for_ack_timeout(endpoint));
       if (reliable_endpoint_pending(endpoint)) 
           reliable_endpoint_retransmit(endpoint);
    }
    

    Or am I missing something?

    opened by alxchk 4
  • Packets too close to `max_packet_size` will fail to receive

    Packets too close to `max_packet_size` will fail to receive

    reliable_endpoint_send_packet will verify that the amount of data sent is not greater than max_packet_size, but then it will add data on top of that (up to RELIABLE_FRAGMENT_HEADER_BYTES + RELIABLE_MAX_PACKET_HEADER_BYTES AFAICT).

    On the other end, reliable_endpoint_receive_packet will also verify that the amount of data received is not greater than max_packet_size -- but since there are header bytes added, this can now exceed the max_packet_size, even if both sender and recipient agree on this number.

    I'd propose a pull request, but I'm not sure which approach is best:

    1. reliable_endpoint_send_packet requires the caller to make sure they're not passing more than max_packet_size - (RELIABLE_FRAGMENT_HEADER_BYTES + RELIABLE_MAX_PACKET_HEADER_BYTES) bytes, so that max_packet_size correctly reflects the largest packet to be sent as seen on the wire, or
    2. reliable_endpoint_receive_packet allows packets up to RELIABLE_FRAGMENT_HEADER_BYTES + RELIABLE_MAX_PACKET_HEADER_BYTES bytes larger than max_packet_size to account for the header added.

    Thoughts?

    opened by jorgenpt 3
  • Fix a memory leak when the sequence buffer wraps

    Fix a memory leak when the sequence buffer wraps

    If the sequence buffers wrap around while a fragmented packet is still waiting for reassembly and we receive a non-fragmented packet that cause us to advance the fragmented sequence buffer past the incomplete fragmented packet, we would not call a cleanup function on the partially reassembled packet, leaving the packet_data to leak.

    This changes the call to reliable_sequence_buffer_advance on the reassembly sequence buffer in the non-fragmented code path to a newly introduced reliable_sequence_buffer_advance_with_cleanup which does the correct cleanup on the reassembly sequence buffer entries.

    opened by jorgenpt 3
  • Should a packet re-transmission be sent as a new packet?

    Should a packet re-transmission be sent as a new packet?

    I am currently playing around with this library and trying to understand how to handle packet retransmission.

    Let's suppose i send a packet with sequence X, i don't get an ack in for some time and decide to resend it. After reading issue #14 i think i should send a new packet with sequence number Y and it is my responsibility to remember that packets with sequence numbers X and Y are actually the same.

    This seems rather inconvenient, increasingly so with multiple re-transmissions of the same packet. Is this how this library is supposed to be used?

    opened by sro5h 3
  • adds test for sequence roll overs while sending packets

    adds test for sequence roll overs while sending packets

    this test shows that the current implementation has a bug when sending a long sequence of regular packets (32767) and then a fragmented packet. since the receiver uses a separate sequence buffer for regular and fragmented packets, they get out of sync, and the fragment_reassembly sequence buffer disregards the packets

    opened by chorakm 3
  • open to a javascript port?

    open to a javascript port?

    I've got a port nearly finished, including all of your unit/soak/fuzz tests (which pass!) The only thing remaining is to put in packet fragmentation/re-assembly. Would you be willing to link to it in this project's README?

    I intend to keep it a faithful port in terms of structure and naming.

    Totally happy to add you (and/or anyone you designate as qualified) as a maintainer.

    I'd also like to publish this to npm

    opened by mreinstein 3
Releases(v1.2)
  • v1.2(Apr 7, 2019)

    Fix a bug where infrequently sent fragments would break the protocol due to sequence buffer rollover at 32k

    Thanks to LiquidBit for spotting this issue.

    Source code(tar.gz)
    Source code(zip)
  • v1.1(Aug 16, 2017)

  • v1.0(Jul 23, 2017)

    This is the initial release of reliable.io

    It is production ready with the following features:

    1. Packet level acks
    2. Fragmentation and reassembly
    3. RTT and packet loss estimates
    4. Support for overriding allocator, log and assert functions.

    It has been extensively unit tested, fuzz tested, works across Windows, Mac and Linux as well as having been successfully integrated into yojimbo for several months now.

    reliable.io is now production ready!

    Source code(tar.gz)
    Source code(zip)
Owner
The Network Protocol Company
The Network Protocol Company
The Network Protocol Company
Winpcap-based network packet capture tool, support TLS (part), UDP, ICMP, TCP, ARP, DNS and other protocol analysis, interface reference wireshark.

Winpcap-based network packet capture tool, support TLS (part), UDP, ICMP, TCP, ARP, DNS and other protocol analysis, interface reference wireshark.

null 54 Dec 26, 2022
the LIBpcap interface to various kernel packet capture mechanism

LIBPCAP 1.x.y by The Tcpdump Group To report a security issue please send an e-mail to [email protected]. To report bugs and other problems, contri

The Tcpdump Group 2.1k Dec 29, 2022
High-speed packet processing framework

PF_RING™ Introduction PF_RING™ is a Linux kernel module and user-space framework that allows you to process packets at high-rates while providing you

ntop 2.3k Dec 27, 2022
network packet indexing and querying

_______ _____.___. ________ _____ _____ \ \\__ | |/ _____/ / \ / _ \ / | \/ | / \ ___ / \ / \ / /_\

64k & stackless-goto 18 Dec 15, 2021
A Simple CLI Network Packet Sniffer

packt packt is a simple CL(command line) network packet sniffer which can run on any unix-like OS including termux (Android). packt works by first ope

null 6 Oct 19, 2022
DPDK / Packet processing experimentation project

flow-orchestrator About This is currently just a platform for me to learn more about DPDK and to have a foundation for some experiments. Building Buil

stefan 4 May 6, 2022
A special version of Packet Batch that utilizes AF_XDP Linux sockets (this should be faster than the standard version, but not as fast as the DPDK).

Packet Batch (AF_XDP) Description This is a special version of Packet Batch that utilizes AF_XDP sockets instead of AF_PACKETv3 (which is what the sta

Packet Batch 17 Nov 9, 2022
A special version of Packet Batch that utilizes the DPDK (this should be faster than the standard version).

Packet Batch (DPDK) Description This is a special version of Packet Batch that utilizes the DPDK, a kernel-bypass library. This does not use any form

Packet Batch 10 Oct 30, 2022
Common files for Packet Batch. Read this for configuration guidance and more!

Packet Batch (Common) Description This is a repository for Packet Batch that includes common files for all versions of Packet Batch to use (standard,

Packet Batch 3 Oct 1, 2022
Packet filter using XDP.

MocTok This is a packet filter using XDP. Usage usage: moctok [options] ... options: -g, --gen Generate XDP program. (string) -a, --atta

Ai Nozaki 13 Aug 25, 2022
Ultra fast and low latency asynchronous socket server & client C++ library with support TCP, SSL, UDP, HTTP, HTTPS, WebSocket protocols and 10K connections problem solution

CppServer Ultra fast and low latency asynchronous socket server & client C++ library with support TCP, SSL, UDP, HTTP, HTTPS, WebSocket protocols and

Ivan Shynkarenka 958 Jan 3, 2023
ENet reliable UDP networking library

Please visit the ENet homepage at http://enet.bespin.org for installation and usage instructions. If you obtained this package from github, the quick

Lee Salzman 2.3k Dec 30, 2022
A modern C++ network library for developing high performance network services in TCP/UDP/HTTP protocols.

evpp Introduction 中文说明 evpp is a modern C++ network library for developing high performance network services using TCP/UDP/HTTP protocols. evpp provid

Qihoo 360 3.2k Jan 5, 2023
QUIC, a multiplexed stream transport over UDP

QUIC, a multiplexed stream transport over UDP QUIC is an experimental protocol aimed at reducing web latency over that of TCP. On the surface, QUIC is

Devsisters Corp. 1.7k Dec 31, 2022
Mongoose Embedded Web Server Library - a multi-protocol embedded networking library with TCP/UDP, HTTP, WebSocket, MQTT built-in protocols, async DNS resolver, and non-blocking API.

Mongoose - Embedded Web Server / Embedded Networking Library Mongoose is a networking library for C/C++. It implements event-driven non-blocking APIs

Cesanta Software 9k Jan 1, 2023
Reliable & unreliable messages over UDP. Robust message fragmentation & reassembly. P2P networking / NAT traversal. Encryption.

GameNetworkingSockets GameNetworkingSockets is a basic transport layer for games. The features are: Connection-oriented API (like TCP) ... but message

Valve Software 6.4k Dec 30, 2022
Built a client-server application using TCP and UDP sockets, in which the clients can subscribe/unsubscribe to various topics.

Built a client-server application using TCP and UDP sockets, in which the clients can subscribe/unsubscribe to various topics.

null 1 Jun 22, 2022
Provide translation, currency conversion, and voting services. First using telnet you create a connection to a TCP socket, then the server connects to 3 UDP sockets hosted on other servers to do tasks.

to run micro servers g++ translator.cpp -o translator ./translator <port 1> g++ voting.cpp -o voting ./voting <port 2> g++ currency_converter.cpp -o c

Jacob Artuso 1 Oct 29, 2021