diff --git a/src/proto/packet.rs b/src/proto/packet.rs index 8642b8e..da98a28 100644 --- a/src/proto/packet.rs +++ b/src/proto/packet.rs @@ -1,7 +1,6 @@ +use std::{io, mem, net}; use std::iter::repeat; -use std::io; use std::io::{Read, Write}; -use std::mem; use byteorder::{ByteOrder, LittleEndian, ReadBytesExt, WriteBytesExt}; use mio::{ @@ -12,6 +11,7 @@ const MAX_PACKET_SIZE: usize = 1 << 20; // 1 MiB const U32_SIZE: usize = 4; const MAX_MESSAGE_SIZE: usize = MAX_PACKET_SIZE - U32_SIZE; +const MAX_PORT: u32 = (1 << 16) - 1; #[derive(Debug)] pub struct Packet { @@ -99,6 +99,21 @@ impl Packet { Ok(()) } + pub fn read_ipv4_addr(&mut self) -> io::Result { + let ip_u32 = try!(self.read_uint()); + Ok(net::Ipv4Addr::from(ip_u32)) + } + + pub fn read_port(&mut self) -> io::Result { + let port_u32 = try!(self.read_uint()); + if port_u32 > MAX_PORT { + return Err(io::Error::new( + io::ErrorKind::Other, + format!("Invalid port number: {}", port_u32))); + } + Ok(port_u32 as u16) + } + pub fn bytes_remaining(&self) -> usize { self.bytes.len() - self.cursor } diff --git a/src/proto/server/response.rs b/src/proto/server/response.rs index 6953ecb..6651bd5 100644 --- a/src/proto/server/response.rs +++ b/src/proto/server/response.rs @@ -4,8 +4,6 @@ use std::net; use super::constants::*; use super::super::packet::Packet; -const MAX_PORT: u32 = (1 << 16) - 1; - /*=================* * SERVER RESPONSE * *=================*/ @@ -100,13 +98,8 @@ impl ConnectToPeerResponse { let username = try!(packet.read_str()); let connection_type = try!(packet.read_str()); - let ip = net::Ipv4Addr::from(try!(packet.read_uint())); - - let port = try!(packet.read_uint()); - if port > MAX_PORT { - return Err( - io::Error::new(io::ErrorKind::Other, "Invalid port number")); - } + let ip = try!(packet.read_ipv4_addr()); + let port = try!(packet.read_port()); let token = try!(packet.read_uint()); let is_privileged = try!(packet.read_bool()); @@ -115,7 +108,7 @@ impl ConnectToPeerResponse { username: username, connection_type: connection_type, ip: ip, - port: port as u16, + port: port, token: token, is_privileged: is_privileged, }) @@ -141,24 +134,25 @@ pub enum LoginResponse { impl LoginResponse { pub fn from_packet(packet: &mut Packet) -> io::Result { let ok = try!(packet.read_bool()); - let resp = if ok { + if ok { let motd = try!(packet.read_str()); - let ip = net::Ipv4Addr::from(try!(packet.read_uint())); + let ip = try!(packet.read_ipv4_addr()); + match packet.read_bool() { Ok(value) => debug!("LoginResponse last field: {}", value), Err(e) => debug!("Error reading LoginResponse field: {:?}", e), } - LoginResponse::LoginOk { + + Ok(LoginResponse::LoginOk { motd: motd, ip: ip, password_md5_opt: None - } + }) } else { - LoginResponse::LoginFail { + Ok(LoginResponse::LoginFail { reason: try!(packet.read_str()) - } - }; - Ok(resp) + }) + } } } @@ -212,16 +206,13 @@ pub struct PeerAddressResponse { impl PeerAddressResponse { fn from_packet(packet: &mut Packet) -> io::Result { let username = try!(packet.read_str()); - let ip = net::Ipv4Addr::from(try!(packet.read_uint())); - let port = try!(packet.read_uint()); - if port > MAX_PORT { - return Err( - io::Error::new(io::ErrorKind::Other, "Invalid port number")); - } + let ip = try!(packet.read_ipv4_addr()); + let port = try!(packet.read_port()); + Ok(PeerAddressResponse { username: username, ip: ip, - port: port as u16, + port: port, }) } }