connection.rs 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. use byteorder::{BigEndian, ByteOrder, ReadBytesExt, WriteBytesExt};
  2. use shannon::ShannonStream;
  3. use std::convert;
  4. use std::io;
  5. use std::io::{Read, Write};
  6. use std::net::TcpStream;
  7. use std::result;
  8. #[derive(Debug)]
  9. pub enum Error {
  10. IoError(io::Error),
  11. Other,
  12. }
  13. pub type Result<T> = result::Result<T, Error>;
  14. impl convert::From<io::Error> for Error {
  15. fn from(err: io::Error) -> Error {
  16. Error::IoError(err)
  17. }
  18. }
  19. pub struct PlainConnection {
  20. stream: TcpStream,
  21. }
  22. #[derive(Clone)]
  23. pub struct CipherConnection {
  24. stream: ShannonStream<TcpStream>,
  25. }
  26. impl PlainConnection {
  27. pub fn connect(ap: &str) -> Result<PlainConnection> {
  28. Ok(PlainConnection {
  29. stream: try!(TcpStream::connect(ap)),
  30. })
  31. }
  32. pub fn send_packet(&mut self, data: &[u8]) -> Result<Vec<u8>> {
  33. self.send_packet_prefix(&[], data)
  34. }
  35. pub fn send_packet_prefix(&mut self, prefix: &[u8], data: &[u8]) -> Result<Vec<u8>> {
  36. let size = prefix.len() + 4 + data.len();
  37. let mut buf = Vec::with_capacity(size);
  38. try!(buf.write(prefix));
  39. try!(buf.write_u32::<BigEndian>(size as u32));
  40. try!(buf.write(data));
  41. try!(self.stream.write(&buf));
  42. try!(self.stream.flush());
  43. Ok(buf)
  44. }
  45. pub fn recv_packet(&mut self) -> Result<Vec<u8>> {
  46. let size = try!(self.stream.read_u32::<BigEndian>()) as usize;
  47. let mut buffer = vec![0u8; size];
  48. BigEndian::write_u32(&mut buffer, size as u32);
  49. try!(self.stream.read_exact(&mut buffer[4..]));
  50. Ok(buffer)
  51. }
  52. pub fn into_stream(self) -> TcpStream {
  53. self.stream
  54. }
  55. }
  56. impl CipherConnection {
  57. pub fn new(stream: TcpStream, recv_key: &[u8], send_key: &[u8]) -> CipherConnection {
  58. CipherConnection { stream: ShannonStream::new(stream, recv_key, send_key) }
  59. }
  60. pub fn send_packet(&mut self, cmd: u8, data: &[u8]) -> Result<()> {
  61. try!(self.stream.write_u8(cmd));
  62. try!(self.stream.write_u16::<BigEndian>(data.len() as u16));
  63. try!(self.stream.write(data));
  64. try!(self.stream.finish_send());
  65. try!(self.stream.flush());
  66. Ok(())
  67. }
  68. pub fn recv_packet(&mut self) -> Result<(u8, Vec<u8>)> {
  69. let cmd = try!(self.stream.read_u8());
  70. let size = try!(self.stream.read_u16::<BigEndian>()) as usize;
  71. let mut data = vec![0; size];
  72. try!(self.stream.read_exact(&mut data));
  73. try!(self.stream.finish_recv());
  74. Ok((cmd, data))
  75. }
  76. }