codec.rs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. use byteorder::{BigEndian, ByteOrder};
  2. use bytes::{BufMut, Bytes, BytesMut};
  3. use shannon::Shannon;
  4. use std::io;
  5. use tokio_io::codec::{Decoder, Encoder};
  6. const HEADER_SIZE: usize = 3;
  7. const MAC_SIZE: usize = 4;
  8. #[derive(Debug)]
  9. enum DecodeState {
  10. Header,
  11. Payload(u8, usize),
  12. }
  13. pub struct APCodec {
  14. encode_nonce: u32,
  15. encode_cipher: Shannon,
  16. decode_nonce: u32,
  17. decode_cipher: Shannon,
  18. decode_state: DecodeState,
  19. }
  20. impl APCodec {
  21. pub fn new(send_key: &[u8], recv_key: &[u8]) -> APCodec {
  22. APCodec {
  23. encode_nonce: 0,
  24. encode_cipher: Shannon::new(send_key),
  25. decode_nonce: 0,
  26. decode_cipher: Shannon::new(recv_key),
  27. decode_state: DecodeState::Header,
  28. }
  29. }
  30. }
  31. impl Encoder for APCodec {
  32. type Item = (u8, Vec<u8>);
  33. type Error = io::Error;
  34. fn encode(&mut self, item: (u8, Vec<u8>), buf: &mut BytesMut) -> io::Result<()> {
  35. let (cmd, payload) = item;
  36. let offset = buf.len();
  37. buf.reserve(3 + payload.len());
  38. buf.put_u8(cmd);
  39. buf.put_u16_be(payload.len() as u16);
  40. buf.extend_from_slice(&payload);
  41. self.encode_cipher.nonce_u32(self.encode_nonce);
  42. self.encode_nonce += 1;
  43. self.encode_cipher.encrypt(&mut buf[offset..]);
  44. let mut mac = [0u8; MAC_SIZE];
  45. self.encode_cipher.finish(&mut mac);
  46. buf.extend_from_slice(&mac);
  47. Ok(())
  48. }
  49. }
  50. impl Decoder for APCodec {
  51. type Item = (u8, Bytes);
  52. type Error = io::Error;
  53. fn decode(&mut self, buf: &mut BytesMut) -> io::Result<Option<(u8, Bytes)>> {
  54. if let DecodeState::Header = self.decode_state {
  55. if buf.len() >= HEADER_SIZE {
  56. let mut header = [0u8; HEADER_SIZE];
  57. header.copy_from_slice(buf.split_to(HEADER_SIZE).as_ref());
  58. self.decode_cipher.nonce_u32(self.decode_nonce);
  59. self.decode_nonce += 1;
  60. self.decode_cipher.decrypt(&mut header);
  61. let cmd = header[0];
  62. let size = BigEndian::read_u16(&header[1..]) as usize;
  63. self.decode_state = DecodeState::Payload(cmd, size);
  64. }
  65. }
  66. if let DecodeState::Payload(cmd, size) = self.decode_state {
  67. if buf.len() >= size + MAC_SIZE {
  68. self.decode_state = DecodeState::Header;
  69. let mut payload = buf.split_to(size + MAC_SIZE);
  70. self.decode_cipher
  71. .decrypt(&mut payload.get_mut(..size).unwrap());
  72. let mac = payload.split_off(size);
  73. self.decode_cipher.check_mac(mac.as_ref())?;
  74. return Ok(Some((cmd, payload.freeze())));
  75. }
  76. }
  77. Ok(None)
  78. }
  79. }