// libTorrent - BitTorrent library // Copyright (C) 2005-2007, Jari Sundell // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // In addition, as a special exception, the copyright holders give // permission to link the code of portions of this program with the // OpenSSL library under certain conditions as described in each // individual source file, and distribute linked combinations // including the two. // // You must obey the GNU General Public License in all respects for // all of the code used other than OpenSSL. If you modify file(s) // with this exception, you may extend this exception to your version // of the file(s), but you are not obligated to do so. If you do not // wish to do so, delete this exception statement from your version. // If you delete this exception statement from all source files in the // program, then also delete it here. // // Contact: Jari Sundell // // Skomakerveien 33 // 3185 Skoppum, NORWAY #include "config.h" #include #include #include "net/listen.h" #include "connection_manager.h" #include "error.h" #include "exceptions.h" namespace torrent { static ConnectionManager::slot_resolver_result_type* resolve_host(const char* host, int family, int socktype, ConnectionManager::slot_resolver_result_type slot) { rak::address_info* ai; int err; if ((err = rak::address_info::get_address_info(host, family, socktype, &ai)) != 0) { slot(NULL, err); return NULL; } rak::socket_address sa; sa.copy(*ai->address(), ai->length()); rak::address_info::free_address_info(ai); slot(sa.c_sockaddr(), 0); return NULL; } ConnectionManager::ConnectionManager() : m_size(0), m_maxSize(0), m_priority(iptos_throughput), m_sendBufferSize(0), m_receiveBufferSize(0), m_encryptionOptions(encryption_none), m_listen(new Listen), m_slotResolver(&resolve_host) { m_bindAddress = (new rak::socket_address())->c_sockaddr(); rak::socket_address::cast_from(m_bindAddress)->sa_inet()->clear(); m_localAddress = (new rak::socket_address())->c_sockaddr(); rak::socket_address::cast_from(m_localAddress)->sa_inet()->clear(); m_proxyAddress = (new rak::socket_address())->c_sockaddr(); rak::socket_address::cast_from(m_proxyAddress)->sa_inet()->clear(); } ConnectionManager::~ConnectionManager() { delete m_listen; delete m_bindAddress; delete m_localAddress; delete m_proxyAddress; } bool ConnectionManager::can_connect() const { return m_size < m_maxSize; } void ConnectionManager::set_send_buffer_size(uint32_t s) { m_sendBufferSize = s; } void ConnectionManager::set_receive_buffer_size(uint32_t s) { m_receiveBufferSize = s; } void ConnectionManager::set_encryption_options(uint32_t options) { #ifdef USE_OPENSSL m_encryptionOptions = options; #else throw input_error("Compiled without encryption support."); #endif } void ConnectionManager::set_bind_address(const sockaddr* sa) { const rak::socket_address* rsa = rak::socket_address::cast_from(sa); if (rsa->family() != rak::socket_address::af_inet) throw input_error("Tried to set a bind address that is not an af_inet address."); rak::socket_address::cast_from(m_bindAddress)->copy(*rsa, rsa->length()); } void ConnectionManager::set_local_address(const sockaddr* sa) { const rak::socket_address* rsa = rak::socket_address::cast_from(sa); if (rsa->family() != rak::socket_address::af_inet) throw input_error("Tried to set a local address that is not an af_inet address."); rak::socket_address::cast_from(m_localAddress)->copy(*rsa, rsa->length()); } void ConnectionManager::set_proxy_address(const sockaddr* sa) { const rak::socket_address* rsa = rak::socket_address::cast_from(sa); if (rsa->family() != rak::socket_address::af_inet) throw input_error("Tried to set a proxy address that is not an af_inet address."); rak::socket_address::cast_from(m_proxyAddress)->copy(*rsa, rsa->length()); } uint32_t ConnectionManager::filter(const sockaddr* sa) { if (m_slotFilter.empty()) return 1; else return m_slotFilter(sa); } bool ConnectionManager::listen_open(port_type begin, port_type end) { if (!m_listen->open(begin, end, rak::socket_address::cast_from(m_bindAddress))) return false; m_listenPort = m_listen->port(); return true; } void ConnectionManager::listen_close() { m_listen->close(); } }