1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
use packet::{
  CompleteGafferPacket,
  GafferPacket
};

use connection::Connection;

use std::net::SocketAddr;

use std::collections::HashMap;


pub mod blocking;
pub mod non_blocking;

pub struct GafferState {
  connections: HashMap<SocketAddr, Connection>
}

impl GafferState {
  pub fn new() -> GafferState {
    GafferState { connections: HashMap::new() }
  }

  pub fn preprocess_packet(&mut self, p: GafferPacket) -> (SocketAddr, Vec<u8>) {
    let connection = self.connections.entry(p.addr).or_insert(Connection::new());
    connection.waiting_packets.enqueue(connection.seq_num, p.clone());
    let final_packet = helpers::assemble_packet(connection.seq_num, p.clone(), connection);
    connection.seq_num = connection.seq_num.wrapping_add(1);
    (p.addr, final_packet.serialized())
  }

  pub fn dropped_packets(&mut self, addr: SocketAddr) -> Vec<GafferPacket> {
    let connection = self.connections.entry(addr).or_insert(Connection::new());
    connection.dropped_packets.drain(..).collect()
  }

  fn receive(&mut self, addr: SocketAddr, packet: CompleteGafferPacket) -> GafferPacket {
    let connection = self.connections.entry(addr).or_insert(Connection::new());
    connection.their_acks.ack(packet.seq);
    let dropped_packets = connection.waiting_packets.ack(packet.ack_seq, packet.ack_field);
    connection.dropped_packets = dropped_packets.into_iter().map(|(_, p)| p).collect();
    GafferPacket { addr: addr, payload: packet.payload }
  }
}



pub mod helpers {
  use connection::Connection;

  use packet::{
    CompleteGafferPacket,
    GafferPacket
  };

  pub fn assemble_packet( seq_num: u16, p: GafferPacket, connection: &Connection) -> CompleteGafferPacket {
    CompleteGafferPacket {
      seq: seq_num,
      ack_seq: connection.their_acks.last_seq,
      ack_field: connection.their_acks.field,
      payload: p.payload
    }
  }
}