Let TcpStream::connect resolve hostnames

This commit is contained in:
Alexis Mousset
2014-05-17 13:11:51 +02:00
parent f4f884730b
commit 6b22cac101
3 changed files with 21 additions and 31 deletions

View File

@@ -18,7 +18,7 @@ use std::io::{IoResult, Reader, Writer};
use std::io::net::ip::Port;
use std::io::net::tcp::TcpStream;
use common::{resolve_host, get_first_word, unquote_email_address};
use common::{get_first_word, unquote_email_address};
use smtp::response::SmtpResponse;
use smtp::extension;
use smtp::extension::SmtpExtension;
@@ -166,22 +166,20 @@ impl<S> SmtpClient<StrBuf, S> {
impl SmtpClient<StrBuf, TcpStream> {
/// Connects to the configured server
pub fn connect(&mut self) -> Result<SmtpResponse<StrBuf>, SmtpResponse<StrBuf>> {
pub fn connect(&mut self) -> IoResult<TcpStream> {
// connect should not be called when the client is already connected
if !self.stream.is_none() {
fail!("The connection is already established");
}
let ip = match resolve_host(self.host.clone().into_owned()) {
Ok(ip) => ip,
Err(..) => fail!("Cannot resolve {:s}", self.host)
};
self.stream = match TcpStream::connect(ip.to_str(), self.port) {
Ok(stream) => Some(stream),
Err(..) => fail!("Cannot connect to {:s}:{:u}", self.host, self.port)
};
// Log the connection
info!("Connection established to {}[{}]:{}", self.my_hostname.clone(), ip, self.port);
// Try to connect
TcpStream::connect(self.host.clone().as_slice(), self.port)
}
/// bla
pub fn get_banner(&mut self) -> Result<SmtpResponse<StrBuf>, SmtpResponse<StrBuf>> {
match self.get_reply() {
Some(response) => match response.with_code(vec!(220)) {
Ok(response) => {
@@ -202,6 +200,14 @@ impl SmtpClient<StrBuf, TcpStream> {
// Connect
match self.connect() {
Ok(stream) => self.stream = Some(stream),
Err(..) => fail!("Cannot connect to the server")
}
// Log the connection
info!("Connection established to {}[{}]:{}", self.host, self.stream.clone().unwrap().peer_name().unwrap().ip, self.port);
match self.get_banner() {
Ok(_) => {},
Err(response) => fail!("Cannot connect to {:s}:{:u}. Server says: {}",
self.host,
@@ -292,7 +298,6 @@ impl<S: Writer + Reader + Clone> SmtpClient<StrBuf, S> {
Ok(string) => string,
Err(..) => fail!("No answer")
};
from_str::<SmtpResponse<StrBuf>>(response)
}

View File

@@ -11,19 +11,8 @@
//!
//! Needs to be organized later
use std::io::net::addrinfo::get_host_addresses;
use std::io::net::ip::IpAddr;
use smtp::CRLF;
/// Resolves an hostname and returns a random IP
pub fn resolve_host(hostname: ~str) -> Result<IpAddr, ()> {
match get_host_addresses(hostname) {
Ok(ip_vector) => Ok(*ip_vector.get(ip_vector.len() - 1)),
Err(..) => Err({})
}
}
/// Adds quotes to emails if needed
pub fn quote_email_address(address: ~str) -> ~str {
match address.len() {
@@ -64,13 +53,6 @@ pub fn get_first_word(string: ~str) -> ~str {
#[cfg(test)]
mod test {
use std::io::net::ip::IpAddr;
#[test]
fn test_resolve_host() {
assert_eq!(super::resolve_host("localhost".to_owned()), Ok(from_str::<IpAddr>("127.0.0.1").unwrap()));
}
#[test]
fn test_quote_email_address() {
assert_eq!(super::quote_email_address("address".to_owned()), "<address>".to_owned());

View File

@@ -33,6 +33,8 @@ pub mod command {
/// SEND, SOML, SAML, TURN
#[deriving(Eq,Clone)]
pub enum SmtpCommand<T> {
/// A fake command
Connect,
/// Extended Hello command
ExtendedHello(T),
/// Hello command
@@ -60,6 +62,7 @@ pub mod command {
impl<T: Show + Str> Show for SmtpCommand<T> {
fn fmt(&self, f: &mut Formatter) -> Result {
f.write(match *self {
Connect => "CONNECT".to_owned(),
ExtendedHello(ref my_hostname) =>
format!("EHLO {}", my_hostname.clone()),
Hello(ref my_hostname) =>