Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.190.156.212] |
|
Сообщ.
#1
,
|
|
|
Нужно создать приложение, которое будет слушать порт 3389 и все соединения на него редиректить на нужный мне ip:3389.
Например, я запускаю свое приложение на 192.168.26.3, все соединения на 192.168.26.3:3389 должны перенаправляться на 192.168.26.5:3389. Ну, и собственно, чтобы RDP работало... Подскажите, в какую сторону копать? Может ссылки найдутся... |
Сообщ.
#2
,
|
|
|
Надо бы поконкретнее.
Слушать сеть на конкретном порту можно и на TCP, и UDP. У вас что именно? Потому что коннект по TCP не редиректится. Сервер TCP принимает трехсторонний хендшейк целиком и полностью, так что редиректить придется вашему приложению после выполнения accept(). accept() возвращает адрес подсоединенного сокета в своем втором параметре. После этого просто ваш сервер превращается в клиента и делается коннект на новый адрес. После установления соединения можете все что приняли - передавать по новому адресу. Есть еще вариант - поэксперементировать с IPHelper и таблицей соединений. Но это думаю будет посложнее. Кстати какая ОС? |
Сообщ.
#3
,
|
|
|
Протокол TCP (RDP), ОС - Windows 2008 Server x64.
А нет ли у вас примера подобной работы с сокетами? |
Сообщ.
#4
,
|
|
|
Фактически вы планируете создать простой прокси-сервер.
Поэтому вам надо смотреть примеры кода для прокси или для переброса портов Или вот это http://www.freeproxy.ru/ru/free_proxy/faq/...ort_mapping.htm Или http://www.algo-rithm.com/downloads/epm.0.1.2.zip Ну вот нашел у себя в архиве какой-то пример. Прикреплённый файлProxy.doc (29,5 Кбайт, скачиваний: 184) |
Сообщ.
#5
,
|
|
|
Oleg2004, спасибо!
Буду пробовать... |
Сообщ.
#6
,
|
|
|
tcp_bouncer 0.0.0.0:3389 нужный_тебе_ip:3389
Usage: tcp_bouncer <in_addr> <in_port> <out_addr> <out_port> <in_addr> and <out_addr> are IPv4 addresses or host names tcp_bouncer.cpp: #include <cstdlib> #include <iostream> #include <sstream> #include <memory> #include <utility> #include <boost/asio.hpp> #include <boost/bind.hpp> #include "stdafx.h" using boost::asio::ip::tcp; using namespace std; class stat_counter { public: stat_counter(): in_bytes_(0), out_bytes_(0) { } void increment_in_bytes(unsigned long inc_value) { in_bytes_ += inc_value; } void increment_out_bytes(unsigned long inc_value) { out_bytes_ += inc_value; } unsigned long long get_in_bytes() const { return in_bytes_; } unsigned long long get_out_bytes() const { return out_bytes_; } bool operator==(const stat_counter& another) const { return this->get_in_bytes() == another.get_in_bytes() && this->get_out_bytes() == another.get_out_bytes(); } bool operator!=(const stat_counter& another) const { return !operator==(another); } private: unsigned long long in_bytes_; unsigned long long out_bytes_; }; class session : public std::enable_shared_from_this<session> { public: session(boost::asio::io_service& io_service, const tcp::endpoint& out_endpoint, unsigned long long session_marker, stat_counter& stat) : in_socket_(io_service), out_endpoint_(out_endpoint), out_socket_(io_service), session_marker_(session_marker), closing_(false), stat_(stat) { } tcp::socket& socket() { return in_socket_; } void start() { do_out_connect(); } private: void do_out_connect() { out_socket_.async_connect(out_endpoint_, boost::bind(&session::handle_out_connect, shared_from_this(), boost::asio::placeholders::error)); } void close_both() { closing_ = true; in_socket_.close(); out_socket_.close(); } void handle_out_connect(const boost::system::error_code& error) { if (!error) { // // Tunnel: // // read from IN, write to OUT // read from OUT, write to IN // // close both if one of them is closed. // start_in_read(); start_out_read(); } else { cerr << "[SESSION #" << session_marker_ << "] Failed to connect to " << out_endpoint_.address().to_string() << ":" << out_endpoint_.port() << "\n"; close_both(); } } void start_in_read() { in_socket_.async_read_some(boost::asio::buffer(in_data_, max_length), boost::bind(&session::handle_in_read, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } void start_out_read() { out_socket_.async_read_some(boost::asio::buffer(out_data_, max_length), boost::bind(&session::handle_out_read, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } void handle_in_read(const boost::system::error_code& error, size_t bytes_transferred) { if (!error) { //cout << "[SESSION #" << session_marker_ << "] Read from IN: " << bytes_transferred << " bytes\n"; stat_.increment_in_bytes(bytes_transferred); boost::asio::async_write(out_socket_, boost::asio::buffer(in_data_, bytes_transferred), boost::bind(&session::handle_out_write, shared_from_this(), boost::asio::placeholders::error)); } else { if (!closing_) { //cerr << "[SESSION #" << session_marker_ << "] Failed to read from IN, closing both\n"; close_both(); } } } void handle_out_write(const boost::system::error_code& error) { if (!error) { start_in_read(); } else { if (!closing_) { cerr << "[SESSION #" << session_marker_ << "] Failed to write to OUT, closing both\n"; close_both(); } } } void handle_out_read(const boost::system::error_code& error, size_t bytes_transferred) { if (!error) { //cout << "[SESSION #" << session_marker_ << "] Read from OUT: " << bytes_transferred << " bytes\n"; stat_.increment_out_bytes(bytes_transferred); boost::asio::async_write(in_socket_, boost::asio::buffer(out_data_, bytes_transferred), boost::bind(&session::handle_in_write, shared_from_this(), boost::asio::placeholders::error)); } else { if (!closing_) { //cerr << "[SESSION #" << session_marker_ << "] Failed to read from OUT, closing both\n"; close_both(); } } } void handle_in_write(const boost::system::error_code& error) { if (!error) { start_out_read(); } else { if (!closing_) { cerr << "[SESSION #" << session_marker_ << "] Failed to write to IN, closing both\n"; close_both(); } } } private: tcp::socket in_socket_; enum { max_length = 1024 }; char in_data_[max_length]; char out_data_[max_length]; const tcp::endpoint& out_endpoint_; tcp::socket out_socket_; unsigned long long session_marker_; bool closing_; stat_counter& stat_; }; static string human_readable_bytecount(unsigned long long bytecount) { stringstream ss; if (bytecount < 1024) { ss << bytecount << " bytes"; return ss.str(); } if (bytecount < 1024*1024) { ss << bytecount / 1024 << " kb"; return ss.str(); } if (bytecount < 1024*1024*1024) { ss << bytecount / 1024 / 1024 << " mb"; return ss.str(); } unsigned long long terabyte = 1024*1024*1024; terabyte *= 1024; if (bytecount < terabyte) { ss << bytecount / 1024 / 1024 / 1024 << " gb"; return ss.str(); } if (bytecount < terabyte*1024) { ss << bytecount / 1024 / 1024 / 1024 / 1024 << " tb"; return ss.str(); } ss << bytecount << " bytes"; return ss.str(); } class server { public: server(boost::asio::io_service& io_service, tcp::endpoint in_endpoint, tcp::endpoint out_endpoint) : acceptor_(io_service, in_endpoint), out_endpoint_(out_endpoint), session_count_(0), timer_(io_service) { do_accept(); set_timer(); } private: void set_timer() { timer_.expires_from_now(boost::posix_time::seconds(1)); timer_.async_wait(boost::bind(&server::handle_timeout, this)); } void handle_timeout() { print_stats(); set_timer(); } void print_stats() const { if (stat_ != prev_stat_) { cout << "Stats: " << human_readable_bytecount(stat_.get_in_bytes()) << " input, " << human_readable_bytecount(stat_.get_out_bytes()) << " output\n"; prev_stat_ = stat_; } } void do_accept() { session_sptr_.reset(new session(acceptor_.get_io_service(), out_endpoint_, session_count_, stat_)); acceptor_.async_accept(session_sptr_->socket(), [this](boost::system::error_code ec) { if (!ec) { session_sptr_->start(); ++session_count_; } do_accept(); }); } tcp::acceptor acceptor_; shared_ptr<session> session_sptr_; tcp::endpoint out_endpoint_; unsigned long long session_count_; boost::asio::deadline_timer timer_; stat_counter stat_; mutable stat_counter prev_stat_; }; // bool resolve_or_convert_address(boost::asio::io_service& io_service, const string& ip_or_hostname, boost::asio::ip::address& result_address) { boost::system::error_code err; boost::asio::ip::address addr( boost::asio::ip::address::from_string(ip_or_hostname, err)); if (!err) { result_address = addr; return true; } else { tcp::resolver resolver(io_service); tcp::resolver::query query(tcp::v4(), ip_or_hostname, ""); tcp::resolver::iterator it = resolver.resolve(query, err); if (!err && it != tcp::resolver::iterator()) { result_address = it->endpoint().address(); return true; } else { return false; } } } int main(int argc, char* argv[]) { try { if (argc != 5) { cout << "Usage: tcp_bouncer <in_addr> <in_port> <out_addr> <out_port>\n"; cout << "<in_addr> and <out_addr> are IPv4 addresses or host names\n"; cout << "\n"; return 1; } boost::asio::io_service io_service; boost::asio::ip::address in_addr, out_addr; if (!resolve_or_convert_address(io_service, argv[1], in_addr)) { cerr << "Bad in_addr - " << argv[1] << "\n"; return -1; } if (!resolve_or_convert_address(io_service, argv[3], out_addr)) { cerr << "Bad out_addr - " << argv[3] << "\n"; return -1; } unsigned short in_port, out_port; in_port = atoi(argv[2]); if (!in_port) { cerr << "Bad in_port - " << argv[2] << "\n"; return -1; } out_port = atoi(argv[4]); if (!out_port) { cerr << "Bad out_port - " << argv[4] << "\n"; return -1; } cout << "in_addr : " << in_addr.to_string() << ":" << in_port << "\n"; cout << "out_addr: " << out_addr.to_string() << ":" << out_port << "\n"; tcp::endpoint in_endpoint(in_addr, in_port); tcp::endpoint out_endpoint(out_addr, out_port); server s(io_service, in_endpoint, out_endpoint); io_service.run(); } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << "\n"; } return 0; } |