GithubHelp home page GithubHelp logo

happyxgang / reliable-udp Goto Github PK

View Code? Open in Web Editor NEW

This project forked from andrewzk/reliable-udp

0.0 2.0 0.0 105 KB

This project implements a reliability layer atop UDP in C.

Makefile 0.63% C 99.37%

reliable-udp's Introduction

Reliable UDP (RUDP)
Author: Andrew Keating <[email protected]>
May 31, 2011

This project implements a reliability layer on top of UDP in C. Reliability is 
achieved using sliding window flow control, ARQ-based retransmissions and 
detection of out-of-order packets.

Usage notes:

To compile, simply run make.

This will compile the RUDP library and two applications which use RUDP. The 
sample applications are vs_send and vs_recv, a file sending application and 
a file receiving application.

Run the receiver: ./vs_recv [-d] port

Run the sender: ./vs_send [-d] host1:port1 [host2:port2] ... file1 [file2]...

Note that vs_send supports sending multiple files simultaneously to multiple 
hosts, but both of these are optional - it is perfectly okay to send a single 
file to a single host.

If executing both the client and server locally, be sure to do so in different 
directories.

Note that vs_send and vs_recv are only sample applications. Other applications 
can be written using RUDP.

The event callback system in RUDP was developed by Olof Hagsand and Peter Sjödin

Author's note:

The RUDP receiver code contains some rather complex nested logic. While it may 
benefit from refactoring, it is mostly a necessary evil due to RUDP's numerous 
protocol states and transitions. 

Technical notes:

For state/session management, we maintain a list of RUDP sockets. Each RUDP 
socket has a list of sessions associated with the socket, in addition to 
function pointers for event handler functions which can be registered by 
applications. Each RUDP session is uniquely identified by the IP address and 
port of the peer with whom the session is established. We logically separate 
sender and receiver sessions, although a single session may contain both a 
sender session and receiver session if both parties exchange data. Within a 
sender session, we maintain a sliding window of transmitted but unacknowledged 
packets, a queue of packets which have not yet been transmitted, and the 
sequence number of the last packet transmitted. Within a receiver session, 
we maintain the sequence number of the last packet received.

We utilize two types of events in RUDP – one which is triggered when data is 
received on a RUDP socket, and another which is triggered when we detect packet 
loss (via a timeout event).

Applications can register two types of events using the RUDP API: one which is 
used to pass received data from the RUDP socket to the application, and another 
which handles other events. We support two other events: RUDP_EVENT_TIMEOUT, 
which indicates that a packet has been retransmitted more than RUDP_MAXRETRANS 
times, and RUDP_EVENT_CLOSE which indicates that an RUDP socket has been closed.

RUDP heavily relies upon sequence numbers to provide reliability. An RUDP 
sequence number is an unsigned 32-bit integer, which is transmitted as a field 
in the RUDP header. When we send a SYN to initiate an RUDP session, a random 
sequence number is generated for the SYN packet. Subsequent packets are sent 
with incremented sequence numbers. ACK packets have a sequence number which is 
1 greater than the sequence number of the packet they acknowledge. When 
comparing sequence numbers, we use macros which handle the multiple cases 
caused by potential integer overflow.

As previously noted, RUDP sender sessions maintain a sliding window of 
transmitted but unacknowledged packets. The size of the sliding window is 
defined by RUDP_WINDOW. When the application provides RUDP with data to be 
sent, we determine whether any slots in the sliding window are open. If so, the 
packet can immediately be added to the window and transmitted. If not, we must 
queue the packet to be delivered once it can acquire a slot in the window.

Upon receiving an ACK packet, we inspect the first item in the sliding window. 
If the ACK packet is intended to acknowledge the first window item, we remove 
this item from the sliding window and shift any subsequent window items to the 
left, creating space in the window for new packets to be sent. As long as 
RUDP_WINDOW is greater than 1, this scheme provides better efficiency than 
stop-and-wait flow control by allowing up to RUDP_WINDOW outstanding 
unacknowledged packets to be sent.

When a non-ACK packet is sent in RUDP, a timer event is registered to occur 
after RUDP_TIMEOUT milliseconds. If the timeout event fires, the packet 
associated with it will be retransmitted, unless the packet has already been 
retransmitted RUDP_MAXRETRANS times, in which case we will trigger a 
RUDP_EVENT_TIMEOUT event.

When we receive an ACK, the timeout event for the packet being acknowledged is 
canceled. In RUDP, timeout events represent the detection of packet loss. Since 
we do not utilize negative acknowledgments, we instead detect packet loss 
implicitly when an ACK is not received.

When an application calls rudp_close on an RUDP socket, we attempt to terminate 
all RUDP sessions which exist on the socket. For each active sender session on 
the socket, we wait until all queued data has been successfully transmitted, 
after which we send a FIN message. When a corresponding ACK has been received 
for the FIN message, we consider the sender session to be complete. Similarly, 
we consider a receiver session to be complete after it has received and 
acknowledged a FIN. Once all sessions on the socket are complete, we close the 
underlying UDP socket, and if the application has registered an RUDP event 
handler, we fire a RUDP_EVENT_CLOSE event.

Tested on Ubuntu 10.04 LTS. Verified memory leak-free by Valgrind.

reliable-udp's People

Contributors

andrewzk avatar

Watchers

James Cloos avatar kevin avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.