bool utp_socket_manager::incoming_packet(error_code const& ec, udp::endpoint const& ep , char const* p, int size) { // UTP_LOGV("incoming packet size:%d\n", size); if (size < int(sizeof(utp_header))) return false; utp_header const* ph = (utp_header*)p; // UTP_LOGV("incoming packet version:%d\n", int(ph->get_version())); if (ph->get_version() != 1) return false; const ptime receive_time = time_now_hires(); // parse out connection ID and look for existing // connections. If found, forward to the utp_stream. boost::uint16_t id = ph->connection_id; // first test to see if it's the same socket as last time // in most cases it is if (m_last_socket && utp_match(m_last_socket, ep, id)) { return utp_incoming_packet(m_last_socket, p, size, ep, receive_time); } std::pair<socket_map_t::iterator, socket_map_t::iterator> r = m_utp_sockets.equal_range(id); for (; r.first != r.second; ++r.first) { if (!utp_match(r.first->second, ep, id)) continue; bool ret = utp_incoming_packet(r.first->second, p, size, ep, receive_time); if (ret) m_last_socket = r.first->second; return ret; } // UTP_LOGV("incoming packet id:%d source:%s\n", id, print_endpoint(ep).c_str()); if (!m_sett.enable_incoming_utp) return false; // if not found, see if it's a SYN packet, if it is, // create a new utp_stream if (ph->get_type() == ST_SYN) { // possible SYN flood. Just ignore if (m_utp_sockets.size() > m_sett.connections_limit * 2) return false; // UTP_LOGV("not found, new connection id:%d\n", m_new_connection); boost::shared_ptr<socket_type> c(new (std::nothrow) socket_type(m_sock.get_io_service())); if (!c) return false; TORRENT_ASSERT(m_new_connection == -1); // create the new socket with this ID m_new_connection = id; instantiate_connection(m_sock.get_io_service(), proxy_settings(), *c, 0, this); utp_stream* str = c->get<utp_stream>(); TORRENT_ASSERT(str); int link_mtu, utp_mtu; mtu_for_dest(ep.address(), link_mtu, utp_mtu); utp_init_mtu(str->get_impl(), link_mtu, utp_mtu); bool ret = utp_incoming_packet(str->get_impl(), p, size, ep, receive_time); if (!ret) return false; m_cb(c); // the connection most likely changed its connection ID here // we need to move it to the correct ID return true; } // #error send reset return false; }
bool utp_socket_manager::incoming_packet(error_code const& ec, udp::endpoint const& ep , char const* p, int size) { // TODO: 2 we may want to take ec into account here. possibly close // connections quicker TORRENT_UNUSED(ec); // UTP_LOGV("incoming packet size:%d\n", size); if (size < int(sizeof(utp_header))) return false; utp_header const* ph = reinterpret_cast<utp_header const*>(p); // UTP_LOGV("incoming packet version:%d\n", int(ph->get_version())); if (ph->get_version() != 1) return false; const time_point receive_time = clock_type::now(); // parse out connection ID and look for existing // connections. If found, forward to the utp_stream. boost::uint16_t id = ph->connection_id; // first test to see if it's the same socket as last time // in most cases it is if (m_last_socket && utp_match(m_last_socket, ep, id)) { return utp_incoming_packet(m_last_socket, p, size, ep, receive_time); } std::pair<socket_map_t::iterator, socket_map_t::iterator> r = m_utp_sockets.equal_range(id); for (; r.first != r.second; ++r.first) { if (!utp_match(r.first->second, ep, id)) continue; bool ret = utp_incoming_packet(r.first->second, p, size, ep, receive_time); if (ret) m_last_socket = r.first->second; return ret; } // UTP_LOGV("incoming packet id:%d source:%s\n", id, print_endpoint(ep).c_str()); if (!m_sett.get_bool(settings_pack::enable_incoming_utp)) return false; // if not found, see if it's a SYN packet, if it is, // create a new utp_stream if (ph->get_type() == ST_SYN) { // possible SYN flood. Just ignore if (int(m_utp_sockets.size()) > m_sett.get_int(settings_pack::connections_limit) * 2) return false; // UTP_LOGV("not found, new connection id:%d\n", m_new_connection); boost::shared_ptr<socket_type> c(new (std::nothrow) socket_type(m_sock.get_io_service())); if (!c) return false; TORRENT_ASSERT(m_new_connection == -1); // create the new socket with this ID m_new_connection = id; instantiate_connection(m_sock.get_io_service(), aux::proxy_settings(), *c , m_ssl_context, this, true, false); utp_stream* str = NULL; #ifdef TORRENT_USE_OPENSSL if (is_ssl(*c)) str = &c->get<ssl_stream<utp_stream> >()->next_layer(); else #endif str = c->get<utp_stream>(); TORRENT_ASSERT(str); int link_mtu, utp_mtu; mtu_for_dest(ep.address(), link_mtu, utp_mtu); utp_init_mtu(str->get_impl(), link_mtu, utp_mtu); bool ret = utp_incoming_packet(str->get_impl(), p, size, ep, receive_time); if (!ret) return false; m_cb(c); // the connection most likely changed its connection ID here // we need to move it to the correct ID return true; } if (ph->get_type() == ST_RESET) return false; // #error send reset return false; }