Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added packet reliability processing. #79

Merged
merged 1 commit into from
Nov 5, 2018
Merged

Added packet reliability processing. #79

merged 1 commit into from
Nov 5, 2018

Conversation

TimonPost
Copy link
Owner

@TimonPost TimonPost commented Oct 31, 2018

This PR is about packet processing described in RFC #65.

!!Note!!
This PR seems big (it is) but there are just a few files needing your attention. They are located in infrastructure module, everything else are just secondary concerns caused by fixing broken tests and moving code to the new channels.

net::connection::virtual_connection.rs and net::udp.rs are also important files where some things have changed.

Channel

A channel processes a packet with a certain reliability. A channel could be responsible for ordering, resending, handling dropped packets etc.

Channel Trait

/// This provides an abstraction for processing packets to their given reliability.
pub trait Channel {
    /// Process an packet before send and return an packet data instance with the given raw packet data.
    fn pre_process(&mut self, payload: &[u8], delivery_method: DeliveryMethod) -> NetworkResult<PacketData>;

    /// Progress an packet on receive and receive the processed data.
    fn process_packet(&mut self, cursor: &mut Cursor<&[u8]>) -> NetworkResult<Vec<u8>>;
}

So we have different instances of channels.

  1. ReliableChannel
    This channel should be used for reliable processing of packets. This channel also has an ordering option for ordering packet, however, this is not implemented yet.
  2. SequencedChannel
    This channel should be used for sequenced packets. Sequenced means only the newest data will be accepted. This channel has the option to be reliable.
  3. UnreliableChannel
    This channel should be used for unreliable processing of packets. This is just bear UDP with some basic header on top of it.

I suggest you look at the code for more information on how I implemented the channels in the code.

Packet Header change.

I also had changed the packet format a little. It was needed for implementing the channels got stuck at the old design. The nice thing now is that the header parser takes in a mutable buffer to which will be written to. It is some kind the same but the following table will show you how the packets are.

Standard header, which will be included in each packet.

pub struct StandardHeader {
    /// crc32 of the protocol version.
    pub protocol_version: u32,
    /// specifies the packet type.
    pub packet_type_id: PacketTypeId,
    /// specifies how this packet should be processed.
    pub delivery_method: DeliveryMethod,
}

Fragment header, this is the header containing header fragment information.
Witch also contains the standard header and the first fragment will also contain

pub struct FragmentHeader {
    standard_header: StandardHeader,
    sequence: u16,
    id: u8,
    num_fragments: u8,
    packet_header: Option<AckedPacketHeader>,
}

Acked packet header wich will be used for reliable packets.

standard_header: StandardHeader,
seq_num: u16,
last_seq: u16,
bit_field: u32,

Overall changes

  • Overal perfromance improvements
  • HeaderParser's parse function takes in mutalble buffer witch is more optimal performance wise than generating them local and return an clone of them.
  • Moved fragmentation stuff into it's own type.
  • Removed SocketState and PacketProcessor this logic can now be found in the ReliableChannel and Fragmenting type.

bonus

@TimonPost TimonPost changed the title Added packet reliability processing WIP | Added packet reliability processing. Oct 31, 2018
@TimonPost TimonPost requested review from LucioFranco and fhaynes and removed request for LucioFranco October 31, 2018 20:05
Copy link
Collaborator

@fhaynes fhaynes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks ok with a quick skim, but it would take hours to do a proper PR with this. As long as the tests have been updated and pass, and they work with my docker-compose stuff, I'm ok with it.

src/net/constants.rs Outdated Show resolved Hide resolved
src/infrastructure/channels/mod.rs Outdated Show resolved Hide resolved
src/infrastructure/channels/mod.rs Outdated Show resolved Hide resolved
src/infrastructure/channels/reliable_channel.rs Outdated Show resolved Hide resolved
src/net/connection/virtual_connection.rs Outdated Show resolved Hide resolved
src/net/connection/virtual_connection.rs Outdated Show resolved Hide resolved
src/net/connection/virtual_connection.rs Outdated Show resolved Hide resolved
src/net/connection/virtual_connection.rs Outdated Show resolved Hide resolved
src/net/connection/virtual_connection.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@LucioFranco LucioFranco left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking really good! Honestly, great work! A lot of comments but mostly questions. I want to take some time to think about the channels. I'm not totally a fan just yet.

src/error/network_error.rs Show resolved Hide resolved
mod reliable_channel;

use infrastructure::DeliveryMethod;
use error::NetworkResult;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

may have missed this before, but this should be called Result to be consistent.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be moved into another issue for error handling. We have to error types and Result already exists.

src/infrastructure/channels/mod.rs Outdated Show resolved Hide resolved
src/infrastructure/channels/reliable_channel.rs Outdated Show resolved Hide resolved
seq_num: u16,
waiting_packets: LocalAckRecord,
their_acks: ExternalAcks,
dropped_packets: Vec<Box<[u8]>>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since vec is already on the heap, could you move a slice into it, instead of a double allocation?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is somewhat complicated, and could better be moved to another issue. This is complicated because LocalAckRecord are gathering dropped ack's and returning them.

use error::NetworkResult;

/// Contains the raw data this packet exists of. Note that a packet can be divided into separate fragments
#[derive(Debug, Default)]
pub struct PacketData {
parts: Vec<RawPacketData>,
parts: Vec<Vec<u8>>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vec of a vec? could you explain this more and why you choose the inner as a vec?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because I removed RawPacketData this was just some unnecessarily code which could be worked away. First I did it since I thought I could have slices here. But I could not accomplish that.

src/packet/packet_data.rs Outdated Show resolved Hide resolved
src/protocol_version.rs Show resolved Hide resolved
tests/common.rs Outdated Show resolved Hide resolved
tests/fragments.rs Outdated Show resolved Hide resolved
@TimonPost TimonPost mentioned this pull request Nov 2, 2018
@LucioFranco
Copy link
Contributor

LucioFranco commented Nov 2, 2018

is this pr still WIP? if not please update the title

@TimonPost TimonPost changed the title WIP | Added packet reliability processing. Added packet reliability processing. Nov 2, 2018
- Channels for processing packets of different reliabilities.
- Changed header format a little to fit current design.
- Moved fragmentation logic to it's own type.
- Global performance improvements by preventing unnecesary alocations with vectors.
- Removed 'SocketState' and 'PacketProcesor' types.
@fhaynes
Copy link
Collaborator

fhaynes commented Nov 5, 2018

bors r+

bors bot added a commit that referenced this pull request Nov 5, 2018
79: Added packet reliability processing. r=fhaynes a=TimonPost

This PR is about packet processing described in RFC #65. 

**!!Note!!**
This PR seems big (it is) but there are just a few files needing your attention. They are located in `infrastructure` module, everything else are just secondary concerns caused by fixing broken tests and moving code to the new channels. 

`net::connection::virtual_connection.rs` and `net::udp.rs` are also important files where some things have changed.

## Channel 
A channel processes a packet with a certain reliability. A channel could be responsible for ordering, resending, handling dropped packets etc.  

_Channel Trait_
```rust
/// This provides an abstraction for processing packets to their given reliability.
pub trait Channel {
    /// Process an packet before send and return an packet data instance with the given raw packet data.
    fn pre_process(&mut self, payload: &[u8], delivery_method: DeliveryMethod) -> NetworkResult<PacketData>;

    /// Progress an packet on receive and receive the processed data.
    fn process_packet(&mut self, cursor: &mut Cursor<&[u8]>) -> NetworkResult<Vec<u8>>;
}
```

So we have different instances of channels. 
1. ReliableChannel
    This channel should be used for reliable processing of packets. This channel also has an ordering option for ordering packet, however, this is not implemented yet.
2. SequencedChannel
     This channel should be used for sequenced packets. Sequenced means only the newest data will be accepted. This channel has the option to be reliable. 
3. UnreliableChannel
    This channel should be used for unreliable processing of packets. This is just bear UDP with some basic header on top of it.

I suggest you look at the code for more information on how I implemented the channels in the code.

## Packet Header change.
I also had changed the packet format a little. It was needed for implementing the channels got stuck at the old design. The nice thing now is that the header parser takes in a mutable buffer to which will be written to. It is some kind the same but the following table will show you how the packets are. 

Standard header, which will be included in each packet.
```rust 
pub struct StandardHeader {
    /// crc32 of the protocol version.
    pub protocol_version: u32,
    /// specifies the packet type.
    pub packet_type_id: PacketTypeId,
    /// specifies how this packet should be processed.
    pub delivery_method: DeliveryMethod,
}
```
Fragment header, this is the header containing header fragment information. 
Witch also contains the standard header and the first fragment will also contain 
```rust
pub struct FragmentHeader {
    standard_header: StandardHeader,
    sequence: u16,
    id: u8,
    num_fragments: u8,
    packet_header: Option<AckedPacketHeader>,
}
```
Acked packet header wich will be used for reliable packets.
```rust
standard_header: StandardHeader,
seq_num: u16,
last_seq: u16,
bit_field: u32,
```
## Overall changes
- Overal perfromance improvements
- HeaderParser's `parse` function takes in mutalble buffer witch is more optimal performance wise than generating them local and return an clone of them. 
- Moved fragmentation stuff into it's own type. 
- Removed `SocketState` and `PacketProcessor` this logic can now be found in the `ReliableChannel` and `Fragmenting` type. 

![bonus](https://media.discordapp.net/attachments/425694112973586452/506815279125495843/DjaXbaVW4AInQXP.png?width=601&height=664)




Co-authored-by: Timon Post <timonpost@hotmail.nl>
@bors
Copy link
Contributor

bors bot commented Nov 5, 2018

Build succeeded

@bors bors bot merged commit db9c0fe into TimonPost:master Nov 5, 2018
@TimonPost TimonPost deleted the channel branch November 26, 2018 09:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants