Beispiel #1
0
    // send an outgoing message to a remote host, if addr is given, then message is sent via UDP
    // return the number of bytes sent
    size_t
    net_ace::
    send (id_t target, char const *msg, size_t size, const Addr *addr)
    {        
        if (_active == false)
            return 0;

        // NOTE: it's possible that connection is already broken, yet still try to access connection
        //       (remote disconnect + local send), may crash. So mutex has to be used

        // a TCP message
        if (addr == NULL)
        {
            std::map<id_t, ConnectInfo>::iterator it;
            timestamp_t now = this->getTimestamp ();

            _conn_mutex.acquire ();

            // need to check if stream object still exists, otherwise may crash
            // (remote disconnection could already remove the connection)
            if ((it = _id2conn.find (target)) != _id2conn.end ())
            {
                // TODO: perhaps actual send can be done outside of mutex (avoid locking too long?)
#ifdef VAST_USE_SSL
                if (it->second.is_secure)
                {
                    ACE_SSL_SOCK_Stream &stream = ((net_ace_handler *)(it->second.stream))->getSSLStream ();  
                    size = stream.send_n (msg, size);
                }
                else
                {
#endif
                    ACE_SOCK_Stream &stream = *((net_ace_handler *)(it->second.stream));
                    size = stream.send_n (msg, size);
#ifdef VAST_USE_SSL                    
                }
#endif                               
                // update the last accessed time for this connection
                it->second.lasttime = now;
            }
            else
                size = 0;

            _conn_mutex.release ();
        }
        // a UDP message
        else
        {
            // TODO: check if two threads accessing same data structure can occur
            ACE_INET_Addr target_addr ((u_short)addr->publicIP.port, (ACE_UINT32)addr->publicIP.host);
            size = _udp->send (msg, size, target_addr);

            // NOTE: there's no time update for UDP connection, as there's no need for connection timeout
        }

        return size;
    }
int method_datagram_t::connect_fd() {
    const netaddr_t& addr = target_addr();

    int fd = socket(addr.sa->sa_family, SOCK_DGRAM, 0);
    if(fd < 0) {
        throw exception_sys_t(log::error, errno, "socket: %m");
    }

    bq_fd_setup(fd);

    if(bq_connect(fd, addr.sa, addr.sa_len, NULL) < 0) {
        throw exception_sys_t(log::error, errno, "connect: %m");
    }

    return fd;
}
Beispiel #3
0
ICMPv6::ICMPv6(const uint8_t *buffer, uint32_t total_sz) 
: _options_size(), reach_time(0), retrans_timer(0)
{
    if(total_sz < sizeof(_header))
        throw malformed_packet();
    std::memcpy(&_header, buffer, sizeof(_header));
    buffer += sizeof(_header);
    total_sz -= sizeof(_header);
    if(has_target_addr()) {
        if(total_sz < ipaddress_type::address_size)
            throw malformed_packet();
        target_addr(buffer);
        buffer += ipaddress_type::address_size;
        total_sz -= ipaddress_type::address_size;
    }
    if(has_dest_addr()) {
        if(total_sz < ipaddress_type::address_size)
            throw malformed_packet();
        dest_addr(buffer);
        buffer += ipaddress_type::address_size;
        total_sz -= ipaddress_type::address_size;
    }
    if(type() == ROUTER_ADVERT) {
        if(total_sz < sizeof(uint32_t) * 2)
            throw malformed_packet();
        const uint32_t *ptr_32 = (const uint32_t*)buffer;
        reach_time = *ptr_32++;
        retrans_timer = *ptr_32++;
        
        buffer += sizeof(uint32_t) * 2;
        total_sz -= sizeof(uint32_t) * 2;
    }
    if(has_options())
        parse_options(buffer, total_sz);
    if(total_sz > 0)
        inner_pdu(new RawPDU(buffer, total_sz));
}
Beispiel #4
0
udp::endpoint observer::target_ep() const
{
	return udp::endpoint(target_addr(), m_port);
}
Beispiel #5
0
Dot11ControlTA::Dot11ControlTA(const address_type &dst_addr, 
  const address_type &target_address) 
: Dot11Control(dst_addr)
{
    target_addr(target_address);
}
void traversal_algorithm::add_entry(node_id const& id
	, udp::endpoint const& addr, unsigned char const flags)
{
	TORRENT_ASSERT(m_node.m_rpc.allocation_size() >= sizeof(find_data_observer));
	auto o = new_observer(addr, id);
	if (!o)
	{
#ifndef TORRENT_DISABLE_LOGGING
		if (get_node().observer() != nullptr)
		{
			get_node().observer()->log(dht_logger::traversal, "[%p] failed to allocate memory or observer. aborting!"
				, static_cast<void*>(this));
		}
#endif
		done();
		return;
	}
	if (id.is_all_zeros())
	{
		o->set_id(generate_random_id());
		o->flags |= observer::flag_no_id;
	}

	o->flags |= flags;

	TORRENT_ASSERT(libtorrent::dht::is_sorted(m_results.begin(), m_results.end()
		, [this](observer_ptr const& lhs, observer_ptr const& rhs)
		{ return compare_ref(lhs->id(), rhs->id(), m_target); }));

	auto iter = std::lower_bound(m_results.begin(), m_results.end(), o
		, [this](observer_ptr const& lhs, observer_ptr const& rhs)
		{ return compare_ref(lhs->id(), rhs->id(), m_target); });

	if (iter == m_results.end() || (*iter)->id() != id)
	{
		if (m_node.settings().restrict_search_ips
			&& !(flags & observer::flag_initial))
		{
#if TORRENT_USE_IPV6
			if (o->target_addr().is_v6())
			{
				address_v6::bytes_type addr_bytes = o->target_addr().to_v6().to_bytes();
				address_v6::bytes_type::const_iterator prefix_it = addr_bytes.begin();
				std::uint64_t const prefix6 = detail::read_uint64(prefix_it);

				if (m_peer6_prefixes.insert(prefix6).second)
					goto add_result;
			}
			else
#endif
			{
				// mask the lower octet
				std::uint32_t const prefix4
					= o->target_addr().to_v4().to_ulong() & 0xffffff00;

				if (m_peer4_prefixes.insert(prefix4).second)
					goto add_result;
			}

			// we already have a node in this search with an IP very
			// close to this one. We know that it's not the same, because
			// it claims a different node-ID. Ignore this to avoid attacks
#ifndef TORRENT_DISABLE_LOGGING
			dht_observer* logger = get_node().observer();
			if (logger != nullptr && logger->should_log(dht_logger::traversal))
			{
				char hex_id[41];
				aux::to_hex(o->id(), hex_id);
				logger->log(dht_logger::traversal
					, "[%p] traversal DUPLICATE node. id: %s addr: %s type: %s"
					, static_cast<void*>(this), hex_id, print_address(o->target_addr()).c_str(), name());
			}
#endif
			return;
		}

	add_result:

		TORRENT_ASSERT((o->flags & observer::flag_no_id)
			|| std::none_of(m_results.begin(), m_results.end()
			, [&id](observer_ptr const& ob) { return ob->id() == id; }));

#ifndef TORRENT_DISABLE_LOGGING
		dht_observer* logger = get_node().observer();
		if (logger != nullptr && logger->should_log(dht_logger::traversal))
		{
			char hex_id[41];
			aux::to_hex(id, hex_id);
			logger->log(dht_logger::traversal
				, "[%p] ADD id: %s addr: %s distance: %d invoke-count: %d type: %s"
				, static_cast<void*>(this), hex_id, print_endpoint(addr).c_str()
				, distance_exp(m_target, id), m_invoke_count, name());
		}
#endif
		iter = m_results.insert(iter, o);

		TORRENT_ASSERT(libtorrent::dht::is_sorted(m_results.begin(), m_results.end()
			, [this](observer_ptr const& lhs, observer_ptr const& rhs)
			{ return compare_ref(lhs->id(), rhs->id(), m_target); }));
	}

	if (m_results.size() > 100)
	{
		for (int i = 100; i < int(m_results.size()); ++i)
		{
			if ((m_results[i]->flags & (observer::flag_queried | observer::flag_failed | observer::flag_alive))
				== observer::flag_queried)
			{
				// set the done flag on any outstanding queries to prevent them from
				// calling finished() or failed()
				m_results[i]->flags |= observer::flag_done;
				TORRENT_ASSERT(m_invoke_count > 0);
				--m_invoke_count;
			}

#if TORRENT_USE_ASSERTS
			m_results[i]->m_was_abandoned = true;
#endif
		}
		m_results.resize(100);
	}
}
Beispiel #7
0
    bool
    net_ace::
    connect (id_t target, unsigned int host, unsigned short port, bool is_secure)
    {
        if (_active == false)
            return false;

        // we're always connected to self
        if (target == _id || isConnected (target))
        {
            printf ("net_ace::connect () connection for [%llu] already exists\n", target);
            return true;
        }

        // convert target address to ACE format
        ACE_INET_Addr target_addr (port, (ACE_UINT32)host);
                
        // create new handler
        net_ace_handler *handler;
        ACE_NEW_RETURN (handler, net_ace_handler, false);    

        // initialize a connection, note that handler is treated as a SOCK_Stream object
        // NOTE 2nd parameter in ACE_Time_Value is in microsecond (not milli)        
        int attempt_count = 0;
        ACE_Time_Value sleeptime (0, 100000);
        ACE_DEBUG ((LM_DEBUG, "connecting to %s:%u (%s)\n", target_addr.get_host_addr (), port, (is_secure ? "secure" : "non-secure")));
        
        // three-second TCP connection timeout
        ACE_Time_Value timeout (3, 0);

        while (attempt_count <= RECONNECT_ATTEMPT)
        {  
            int result;

#ifdef VAST_USE_SSL
            if (is_secure)
            {
                result = _SSL_connector.connect (handler->getSSLStream (), target_addr, &timeout);
                printf ("making secure connection, result: %d\n", result);
            }
            else
#endif
                result = _connector.connect (*handler, target_addr, &timeout);

            // if attempt succeed
            if (result == 0)
                break;
                            
            attempt_count++;
            ACE_DEBUG ((LM_DEBUG, "connect %s:%d failed (try %d):\n", target_addr.get_host_addr (), target_addr.get_port_number (), attempt_count));
            ACE_OS::sleep (sleeptime);
        }

        // see if we've failed
        if (attempt_count > RECONNECT_ATTEMPT)
            ACE_ERROR_RETURN ((LM_ERROR, "connect to %s:%u (%s) failed after %d re-attempts\n", target_addr.get_host_addr (), target_addr.get_port_number (), (is_secure ? "secure" : "normal"), attempt_count), false);
        
        // open the handler object, this will 
        // 1) register handler with reactor 2) cause socket_connected () be called
        if (handler->open (_reactor, this, target) == -1)
        {
            handler->close();
            return false;
        }
        
        ACE_DEBUG ((LM_DEBUG, "(%5t) connect(): connected to (%s:%d)\n", target_addr.get_host_addr (), target_addr.get_port_number ()));

        return true;
    }