mirror of
https://github.com/shadowsocks/shadowsocks-rust.git
synced 2026-02-09 01:59:16 +08:00
send error replies
This commit is contained in:
@@ -26,8 +26,7 @@ pub use self::server::RelayServer;
|
||||
|
||||
use std::fmt::{Show, Formatter, FormatError};
|
||||
use std::io::net::ip::{SocketAddr, Port};
|
||||
use std::io::TcpStream;
|
||||
use std::io::net::ip::{Ipv4Addr, Ipv6Addr};
|
||||
use std::io::net::ip::{Ipv4Addr, Ipv6Addr};
|
||||
|
||||
pub mod tcprelay;
|
||||
// pub mod udprelay;
|
||||
@@ -145,8 +144,3 @@ pub fn parse_request_header(buf: &[u8]) -> Result<(uint, Sock5AddrType), u8> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn send_error_reply(stream: &mut TcpStream, err_code: u8) {
|
||||
let reply = [SOCKS5_VERSION, err_code, 0x00];
|
||||
stream.write(reply).ok().expect("Error occurs while sending errors");
|
||||
}
|
||||
|
||||
@@ -27,18 +27,20 @@ extern crate log;
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::io::{Listener, TcpListener, Acceptor, TcpStream};
|
||||
use std::io::{EndOfFile, TimedOut, NotConnected};
|
||||
use std::io::{EndOfFile, TimedOut, NotConnected,
|
||||
ConnectionFailed, ConnectionRefused, ConnectionReset, ConnectionAborted};
|
||||
use std::io::net::ip::Port;
|
||||
use std::io::net::ip::{Ipv4Addr, Ipv6Addr};
|
||||
|
||||
use config::Config;
|
||||
|
||||
use relay::Relay;
|
||||
use relay::{parse_request_header, send_error_reply};
|
||||
use relay::parse_request_header;
|
||||
use relay::tcprelay::send_error_reply;
|
||||
use relay::{SOCKS5_VERSION, SOCKS5_AUTH_METHOD_NONE};
|
||||
use relay::{SOCKS5_CMD_TCP_CONNECT, SOCKS5_CMD_TCP_BIND, SOCKS5_CMD_UDP_ASSOCIATE};
|
||||
use relay::{SOCKS5_ADDR_TYPE_IPV6, SOCKS5_ADDR_TYPE_IPV4};
|
||||
use relay::{SOCKS5_REPLY_COMMAND_NOT_SUPPORTED};
|
||||
use relay::{SOCKS5_REPLY_COMMAND_NOT_SUPPORTED, SOCKS5_REPLY_HOST_UNREACHABLE, SOCKS5_REPLY_NETWORK_UNREACHABLE};
|
||||
use relay::SOCKS5_REPLY_SUCCEEDED;
|
||||
use relay::loadbalancing::server::{LoadBalancer, RoundRobin};
|
||||
|
||||
@@ -224,9 +226,21 @@ impl TcpRelayLocal {
|
||||
(header_buf.slice_to(header_len).to_vec(), addr)
|
||||
};
|
||||
|
||||
let mut remote_stream = TcpStream::connect(server_addr.as_slice(),
|
||||
server_port)
|
||||
.ok().expect("Error occurs while connecting to remote server");
|
||||
let mut remote_stream = match TcpStream::connect(server_addr.as_slice(),
|
||||
server_port) {
|
||||
Ok(s) => s,
|
||||
Err(err) => {
|
||||
match err.kind {
|
||||
ConnectionAborted | ConnectionReset | ConnectionRefused | ConnectionFailed => {
|
||||
send_error_reply(stream, SOCKS5_REPLY_HOST_UNREACHABLE);
|
||||
},
|
||||
_ => {
|
||||
send_error_reply(stream, SOCKS5_REPLY_NETWORK_UNREACHABLE);
|
||||
}
|
||||
}
|
||||
fail!("Failed to connect remote server: {}", err);
|
||||
}
|
||||
};
|
||||
|
||||
let mut cipher = cipher::with_name(encrypt_method.as_slice(),
|
||||
password.as_slice().as_bytes())
|
||||
@@ -262,6 +276,7 @@ impl TcpRelayLocal {
|
||||
&mut cipher));
|
||||
},
|
||||
SOCKS5_CMD_TCP_BIND => {
|
||||
send_error_reply(stream, SOCKS5_REPLY_COMMAND_NOT_SUPPORTED);
|
||||
unimplemented!();
|
||||
},
|
||||
SOCKS5_CMD_UDP_ASSOCIATE => {
|
||||
|
||||
@@ -26,5 +26,13 @@ extern crate log;
|
||||
|
||||
extern crate native;
|
||||
|
||||
use std::io::TcpStream;
|
||||
use relay::SOCKS5_VERSION;
|
||||
|
||||
pub mod local;
|
||||
pub mod server;
|
||||
|
||||
pub fn send_error_reply(stream: &mut TcpStream, err_code: u8) {
|
||||
let reply = [SOCKS5_VERSION, err_code, 0x00];
|
||||
stream.write(reply).ok().expect("Error occurs while sending errors");
|
||||
}
|
||||
|
||||
@@ -32,7 +32,8 @@ use std::io::{EndOfFile, TimedOut};
|
||||
use config::{Config, SingleServer, MultipleServer};
|
||||
use relay::Relay;
|
||||
use relay::{parse_request_header, Sock5SocketAddr, Sock5DomainNameAddr};
|
||||
use relay::send_error_reply;
|
||||
use relay::tcprelay::send_error_reply;
|
||||
use relay::{SOCKS5_REPLY_HOST_UNREACHABLE};
|
||||
|
||||
use crypto::cipher;
|
||||
use crypto::cipher::Cipher;
|
||||
@@ -194,23 +195,35 @@ impl Relay for TcpRelayServer {
|
||||
info!("Connecting to {}", addr);
|
||||
let mut remote_stream = match addr {
|
||||
Sock5SocketAddr(sockaddr) => {
|
||||
TcpStream::connect(sockaddr.ip.to_string().as_slice(), sockaddr.port)
|
||||
.ok().expect("Unable to connect to remote")
|
||||
match TcpStream::connect(sockaddr.ip.to_string().as_slice(), sockaddr.port) {
|
||||
Ok(s) => s,
|
||||
Err(err) => {
|
||||
send_error_reply(&mut stream, SOCKS5_REPLY_HOST_UNREACHABLE);
|
||||
fail!("Unable to connect {}: {}", sockaddr, err)
|
||||
}
|
||||
}
|
||||
},
|
||||
Sock5DomainNameAddr(domainaddr) => {
|
||||
let addrs = match get_host_addresses(domainaddr.domain_name.as_slice()) {
|
||||
Ok(ipaddrs) => ipaddrs,
|
||||
Err(e) => {
|
||||
send_error_reply(&mut stream, SOCKS5_REPLY_HOST_UNREACHABLE);
|
||||
fail!("Error occurs while get_host_addresses: {}", e);
|
||||
}
|
||||
};
|
||||
|
||||
if addrs.len() == 0 {
|
||||
send_error_reply(&mut stream, SOCKS5_REPLY_HOST_UNREACHABLE);
|
||||
fail!("Cannot resolve host {}, empty host list", domainaddr.domain_name);
|
||||
}
|
||||
|
||||
TcpRelayServer::connect_remote(addrs, domainaddr.port)
|
||||
.expect(format!("Unable to resolve {}", domainaddr.domain_name).as_slice())
|
||||
match TcpRelayServer::connect_remote(addrs, domainaddr.port) {
|
||||
Some(s) => s,
|
||||
None => {
|
||||
send_error_reply(&mut stream, SOCKS5_REPLY_HOST_UNREACHABLE);
|
||||
fail!("Unable to resolve host {}", domainaddr)
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user