static void CountSSMLeave(const address &group, const address &source) { address source_addr; char tmp[64], tmp2[64]; GroupMap::iterator g = groupMap.find(group); assert(g != groupMap.end()); source_addr.set_family(source.family()); source_addr.copy_address(source); source_addr.set_port(0); SourceMap::iterator s = g->second.find(source_addr); assert(s != g->second.end()); SourceSet::iterator ss = s->second.find(source); if (ss == s->second.end()) { return; } if (verbose) info("Removing beacon %s from (%s, %s)", source.to_string(tmp, sizeof(tmp)), source_addr.to_string(tmp2, sizeof(tmp2)), group.to_string(tmp2, sizeof(tmp2))); s->second.erase(ss); if (s->second.empty()) { if (verbose) info("No more beacons for (%s, %s), leaving group", source_addr.to_string(tmp, sizeof(tmp)), group.to_string(tmp2, sizeof(tmp2))); SSMLeave(ssmMcastSock,group, source_addr); g->second.erase(s); } if (g->second.empty()) { if (verbose) info("No more sources, unregistering group %s, ", group.to_string(tmp, sizeof(tmp))); groupMap.erase(g); } }
int ip_filter::access(address const& addr) const { if (addr.is_v4()) return m_filter4.access(addr.to_v4()); assert(addr.is_v6()); return m_filter6.access(addr.to_v6()); }
static void CountSSMJoin(const address &group, const address &source) { address source_addr; char tmp[64], tmp2[64], tmp3[64]; source_addr.set_family(source.family()); source_addr.copy_address(source); source_addr.set_port(0); GroupMap::iterator g = groupMap.find(group); if (g == groupMap.end()) { if (verbose) info("Registering SSM group %s", group.to_string(tmp, sizeof(tmp))); g = groupMap.insert(std::make_pair(group, SourceMap())).first; } SourceMap::iterator s = g->second.find(source_addr); if (s == g->second.end()) { if (verbose) info("Joining (%s, %s)", source_addr.to_string(tmp, sizeof(tmp)), group.to_string(tmp2, sizeof(tmp2))); if (SSMJoin(ssmMcastSock, group, source_addr) < 0) { if (verbose) info("Join failed, reason: %s", strerror(errno)); return; } else { s = g->second.insert(std::make_pair(source_addr, SourceSet())).first; } } SourceSet::iterator ss = s->second.find(source); if (ss == s->second.end()) { if (verbose) info("Adding beacon %s to (%s, %s)", source.to_string(tmp, sizeof(tmp)), source_addr.to_string(tmp2, sizeof(tmp2)), group.to_string(tmp3, sizeof(tmp3))); s->second.insert(source); } }
int send_report(int type) { int len; len = build_report(buffer, bufferLen, type == SSM_REPORT ? STATS_REPORT : type, true); if (len < 0) return len; int res; if (type == SSM_REPORT) { if ((res = sendto(mcastSock, buffer, len, 0, ssmProbeAddr.saddr(), ssmProbeAddr.addrlen())) < 0) d_log(LOG_DEBUG, "Failed to send SSM report: %s", strerror(errno)); else bytesSent += res; } else { for (vector<address>::const_iterator i = redist.begin(); i != redist.end(); ++i) { char tmp[64]; if (verbose) d_log(LOG_DEBUG, "Sending Report to %s", i->to_string(tmp, sizeof(tmp))); if ((res = sendto(mcastSock, buffer, len, 0, i->saddr(), i->addrlen())) < 0) d_log(LOG_DEBUG, "Failed to send report to %s: %s", i->to_string(tmp, sizeof(tmp)), strerror(errno)); else bytesSent += res; } } return 0; }
address external_ip::external_address(address const& ip) const { address ext = m_vote_group[ip.is_v6()].external_address(); #if TORRENT_USE_IPV6 if (ip.is_v6() && ext == address_v4()) return address_v6(); #endif return ext; }
// private hosts::iterator hosts::find(const address& host) { const auto found = [&host](const address& entry) { return entry.port() == host.port() && entry.ip() == host.ip(); }; return std::find_if(buffer_.begin(), buffer_.end(), found); }
bool address::is_equal(const address &a) const { if (stor.ss_family != a.stor.ss_family) return false; if (stor.ss_family == AF_INET6) return memcmp(&v6()->sin6_addr, &a.v6()->sin6_addr, sizeof(in6_addr)) == 0; else if (stor.ss_family == AF_INET) return v4()->sin_addr.s_addr == a.v4()->sin_addr.s_addr; return false; }
tcp::endpoint utp_socket_manager::local_endpoint(address const& remote, error_code& ec) const { tcp::endpoint socket_ep = m_sock.local_endpoint(ec); // first enumerate the routes in the routing table if (time_now() - m_last_route_update > seconds(60)) { m_last_route_update = time_now(); error_code ec; m_routes = enum_routes(m_sock.get_io_service(), ec); if (ec) return socket_ep; } if (m_routes.empty()) return socket_ep; // then find the best match ip_route* best = &m_routes[0]; for (std::vector<ip_route>::iterator i = m_routes.begin() , end(m_routes.end()); i != end; ++i) { if (is_any(i->destination) && i->destination.is_v4() == remote.is_v4()) { best = &*i; continue; } if (match_addr_mask(remote, i->destination, i->netmask)) { best = &*i; continue; } } // best now tells us which interface we would send over // for this target. Now figure out what the local address // is for that interface if (time_now() - m_last_if_update > seconds(60)) { m_last_if_update = time_now(); error_code ec; m_interfaces = enum_net_interfaces(m_sock.get_io_service(), ec); if (ec) return socket_ep; } for (std::vector<ip_interface>::iterator i = m_interfaces.begin() , end(m_interfaces.end()); i != end; ++i) { if (i->interface_address.is_v4() != remote.is_v4()) continue; if (strcmp(best->name, i->name) == 0) return tcp::endpoint(i->interface_address, socket_ep.port()); } return socket_ep; }
int ip_filter::access(address const& addr) const { if (addr.is_v4()) return m_filter4.access(addr.to_v4().to_bytes()); #if TORRENT_USE_IPV6 TORRENT_ASSERT(addr.is_v6()); return m_filter6.access(addr.to_v6().to_bytes()); #else return 0; #endif }
bool address::copy_address(const address &source) { if (family() != source.family()) return false; if (stor.ss_family == AF_INET6) v6()->sin6_addr = source.v6()->sin6_addr; else v4()->sin_addr = source.v4()->sin_addr; return true; }
static int send_nprobe(const address &addr, uint32_t &seq) { int len; len = build_probe(buffer, bufferLen, seq, get_time_of_day()); seq++; len = sendto(mcastSock, buffer, len, 0, addr.saddr(), addr.addrlen()); if (len > 0) bytesSent += len; return len; }
bool in_subnet(address const& addr, ip_interface const& iface) { if (addr.is_v4() != iface.interface_address.is_v4()) return false; // since netmasks seems unreliable for IPv6 interfaces // (MacOS X returns AF_INET addresses as bitmasks) assume // that any IPv6 address belongs to the subnet of any // interface with an IPv6 address if (addr.is_v6()) return true; return (addr.to_v4().to_ulong() & iface.netmask.to_v4().to_ulong()) == (iface.interface_address.to_v4().to_ulong() & iface.netmask.to_v4().to_ulong()); }
void write_address(address const& a, OutIt& out) { if (a.is_v4()) { write_uint32(a.to_v4().to_ulong(), out); } else if (a.is_v6()) { address_v6::bytes_type bytes = a.to_v6().to_bytes(); std::copy(bytes.begin(), bytes.end(), out); } }
address mask_address(const address& addrIn, uint8_t prefixLen) { if (addrIn.is_v4()) { prefixLen = std::min<uint8_t>(prefixLen, 32); uint32_t mask = get_subnet_mask_v4(prefixLen); return address_v4(addrIn.to_v4().to_ulong() & mask); } struct in6_addr mask; struct in6_addr addr6; prefixLen = std::min<uint8_t>(prefixLen, 128); compute_ipv6_subnet(addrIn.to_v6(), prefixLen, &mask, &addr6); address_v6::bytes_type data; std::memcpy(data.data(), &addr6, sizeof(addr6)); return address_v6(data); }
void utp_socket_manager::mtu_for_dest(address const& addr, int& link_mtu, int& utp_mtu) { int mtu = 0; if (is_teredo(addr)) mtu = TORRENT_TEREDO_MTU; else mtu = TORRENT_ETHERNET_MTU; #if defined __APPLE__ // apple has a very strange loopback. It appears you can't // send messages of the reported MTU size, and you don't get // EWOULDBLOCK either. if (is_loopback(addr)) { if (is_teredo(addr)) mtu = TORRENT_TEREDO_MTU; else mtu = TORRENT_ETHERNET_MTU; } #endif // clamp the MTU within reasonable bounds if (mtu < TORRENT_INET_MIN_MTU) mtu = TORRENT_INET_MIN_MTU; else if (mtu > TORRENT_INET_MAX_MTU) mtu = TORRENT_INET_MAX_MTU; link_mtu = mtu; mtu -= TORRENT_UDP_HEADER; if (m_sock.get_proxy_settings().type == settings_pack::socks5 || m_sock.get_proxy_settings().type == settings_pack::socks5_pw) { // this is for the IP layer address proxy_addr = m_sock.proxy_addr().address(); if (proxy_addr.is_v4()) mtu -= TORRENT_IPV4_HEADER; else mtu -= TORRENT_IPV6_HEADER; // this is for the SOCKS layer mtu -= TORRENT_SOCKS5_HEADER; // the address field in the SOCKS header if (addr.is_v4()) mtu -= 4; else mtu -= 16; } else { if (addr.is_v4()) mtu -= TORRENT_IPV4_HEADER; else mtu -= TORRENT_IPV6_HEADER; } utp_mtu = (std::min)(mtu, restrict_mtu()); }
std::string address_to_bytes(address const& a) { #if LIBED2K_USE_IPV6 if (a.is_v6()) { address_v6::bytes_type b = a.to_v6().to_bytes(); return std::string((char*)&b[0], b.size()); } else #endif { address_v4::bytes_type b = a.to_v4().to_bytes(); return std::string((char*)&b[0], b.size()); } }
bool SetHops(int sock, const address &addr, int ttl) { if (addr.optlevel() == IPPROTO_IPV6) { if (setsockopt(sock, addr.optlevel(), IPV6_MULTICAST_HOPS, &ttl, sizeof(ttl)) != 0) { return false; } } else { TTLType _ttl = ttl; if (setsockopt(sock, addr.optlevel(), IP_MULTICAST_TTL, &_ttl, sizeof(_ttl)) != 0) { return false; } } return true; }
bool equal(const address& left, const address& right) { const auto left_addresses = left.addresses(); const auto right_addresses = right.addresses(); bool same = (left_addresses.size() == right_addresses.size()); for (size_t i = 0; (i < left_addresses.size()) && same; i++) { same = (left_addresses[i] == right_addresses[i]) && (left_addresses[i].timestamp() == right_addresses[i].timestamp()); } return same; }
int udp_socket::sendto(char const* msg, std::size_t len, address const& addr) { return ::sendto(get_descriptor(*this), msg, len, 0, reinterpret_cast<sockaddr const*>(addr.data()), sizeof(sockaddr)); }
inline T address_cast(const address& addr, typename enable_if<is_same<T, address_v6>::value>::type* = 0) { if (!addr.is_v6()) throw bad_address_cast(); return get_v6_helper(addr); }
void write_address(address const& a, OutIt&& out) { #if TORRENT_USE_IPV6 if (a.is_v4()) { #endif write_uint32(a.to_v4().to_ulong(), out); #if TORRENT_USE_IPV6 } else if (a.is_v6()) { for (auto b : a.to_v6().to_bytes()) write_uint8(b, out); } #endif }
void broadcast_socket::open_unicast_socket( io_service& ios, address const& addr, address_v4 const& mask) { using namespace asio::ip::multicast; error_code ec; boost::shared_ptr<datagram_socket> s(new datagram_socket(ios)); s->open(addr.is_v4() ? udp::v4() : udp::v6(), ec); if (ec) return; s->bind(udp::endpoint(addr, 0), ec); if (ec) return; m_unicast_sockets.push_back(socket_entry(s, mask)); socket_entry& se = m_unicast_sockets.back(); // allow sending broadcast messages asio::socket_base::broadcast option(true); s->set_option(option, ec); if (!ec) se.broadcast = true; #if defined LIBED2K_ASIO_DEBUGGING add_outstanding_async("broadcast_socket::on_receive"); #endif s->async_receive_from( asio::buffer(se.buffer, sizeof(se.buffer)), se.remote, boost::bind(&broadcast_socket::on_receive, this, &se, _1, _2)); ++m_outstanding_operations; }
void broadcast_socket::open_multicast_socket( io_service& ios, address const& addr, bool loopback, error_code& ec) { using namespace asio::ip::multicast; boost::shared_ptr<datagram_socket> s(new datagram_socket(ios)); s->open(addr.is_v4() ? udp::v4() : udp::v6(), ec); if (ec) return; s->set_option(datagram_socket::reuse_address(true), ec); if (ec) return; s->bind(udp::endpoint(addr, m_multicast_endpoint.port()), ec); if (ec) return; s->set_option(join_group(m_multicast_endpoint.address()), ec); if (ec) return; s->set_option(hops(255), ec); if (ec) return; s->set_option(enable_loopback(loopback), ec); if (ec) return; m_sockets.push_back(socket_entry(s)); socket_entry& se = m_sockets.back(); #if defined LIBED2K_ASIO_DEBUGGING add_outstanding_async("broadcast_socket::on_receive"); #endif s->async_receive_from(asio::buffer(se.buffer, sizeof(se.buffer)), se.remote, boost::bind(&broadcast_socket::on_receive, this, &se, _1, _2)); ++m_outstanding_operations; }
void write_address(address const& a, OutIt& out) { #if TORRENT_USE_IPV6 if (a.is_v4()) { #endif write_uint32(a.to_v4().to_ulong(), out); #if TORRENT_USE_IPV6 } else if (a.is_v6()) { address_v6::bytes_type bytes = a.to_v6().to_bytes(); std::copy(bytes.begin(), bytes.end(), out); } #endif }
bool network::has_addres(address ip) { unsigned int m=-1; m<<=32-_mask; if(addr()==(ip.addr()&m)) return true; return false; }
int _McastListenOldAPI(int sock, const address &grpaddr) { if (grpaddr.family() == AF_INET6) { ipv6_mreq mreq; mreq.ipv6mr_interface = mcastInterface; mreq.ipv6mr_multiaddr = grpaddr.v6()->sin6_addr; return setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)); } else { ip_mreq mreq; memset(&mreq, 0, sizeof(mreq)); // Specifying the interface doesn't work, there's ip_mreqn in linux.. // but what about other OSs? -hugo mreq.imr_multiaddr = grpaddr.v4()->sin_addr; return setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)); } }
void connection::connect(const address & _address) { printf("client trying: %d.%d.%d.%d:%d\n", _address.getA(), _address.getB(), _address.getC(), _address.getD(), _address.getPort() ); if(!m_keyPool.empty()) /// If the key pool isn't empty { /// access mailList based on the key pools returned value /// and set mailList element up with the new connections /// data m_mailList[m_keyPool.back()].first->m_state = e_connecting; m_mailList[m_keyPool.back()].first->m_address = _address; m_mailList[m_keyPool.back()].first->m_timeoutAccumulator = 0.0f; m_mailList[m_keyPool.back()].first->m_stats.reset(); m_mailList[m_keyPool.back()].second = 0; /// add the key onto newConKeys and pop it off of the keyPool /// as it is now in use. m_newConnKeys.push_back(m_keyPool.back()); ///Receive key m_keyPool.pop_back(); return; } /// If The key pool Is empty /// allocate a new sender /// initialise it as a new connection /// push it back onto mailList /// then push it's array position onto newConKeys sender* n_mailer = new sender(m_maxSequence); n_mailer->m_address = _address; n_mailer->m_state = e_connecting; n_mailer->m_timeoutAccumulator = 0.0f; unsigned short sendKey = 0; m_mailList.push_back(std::pair<sender*, unsigned short>(n_mailer, sendKey)); m_newConnKeys.push_back(m_mailList.size()-1); /// Receive key }
bool socket::send(const address & destination, const void * data, int size) { assert(data); assert(size > 0); if (m_socket == 0) return false; assert(destination.getAddress() != 0); assert(destination.getPort() != 0); sockaddr_in address; address.sin_family = AF_INET; address.sin_addr.s_addr = htonl(destination.getAddress()); address.sin_port = htons((unsigned short) destination.getPort()); int sent_bytes = sendto(m_socket, (const char*)data, size, 0, (sockaddr*)&address, sizeof(sockaddr_in)); return sent_bytes == size; }
static address v4_mapped(const address& addr) { bytes_type v4_bytes = addr.to_bytes(); bytes_type v6_bytes; memset(&v6_bytes[0], 0, 10); v6_bytes[10] = 0xFF; v6_bytes[11] = 0xFF; memcpy(&v6_bytes[12], &v4_bytes[0], 4); return address(v6_bytes, 16); }
void write_address(address const& a, OutIt& out) { #if TORRENT_USE_IPV6 if (a.is_v4()) { #endif write_uint32(a.to_v4().to_ulong(), out); #if TORRENT_USE_IPV6 } else if (a.is_v6()) { typedef address_v6::bytes_type bytes_t; bytes_t bytes = a.to_v6().to_bytes(); for (bytes_t::iterator i = bytes.begin() , end(bytes.end()); i != end; ++i) write_uint8(*i, out); } #endif }