bool UdpSocket::IsMulticastLoop() { if (GetSocket() == INVALID_SOCKET) { CreateConnection(); } #ifdef ENABLE_IPV6 #ifdef IPPROTO_IPV6 if (IsIpv6()) { int is_loop = 0; socklen_t size = sizeof(int); if (getsockopt(GetSocket(), IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (char *)&is_loop, &size) == -1) { Handler().LogError(this, "IsMulticastLoop(ipv6)", Errno, StrError(Errno), LOG_LEVEL_WARNING); } return is_loop ? true : false; } #endif #endif int is_loop = 0; socklen_t size = sizeof(int); if (getsockopt(GetSocket(), SOL_IP, IP_MULTICAST_LOOP, (char *)&is_loop, &size) == -1) { Handler().LogError(this, "IsMulticastLoop(ipv4)", Errno, StrError(Errno), LOG_LEVEL_WARNING); } return is_loop ? true : false; }
void UdpSocket::SetMulticastDefaultInterface(const std::string& intf, int if_index) { if (GetSocket() == INVALID_SOCKET) { CreateConnection(); } #ifdef ENABLE_IPV6 #ifdef IPPROTO_IPV6 if (IsIpv6()) { struct in6_addr a; if (Utility::u2ip( intf, a )) { SetMulticastDefaultInterface( a, if_index ); } return; } #endif #endif ipaddr_t a; if (Utility::u2ip( intf, a )) { SetMulticastDefaultInterface( a, if_index ); } }
void UdpSocket::CreateConnection() { #ifdef ENABLE_IPV6 #ifdef IPPROTO_IPV6 if (IsIpv6()) { if (GetSocket() == INVALID_SOCKET) { SOCKET s = CreateSocket(AF_INET6, SOCK_DGRAM, "udp"); if (s == INVALID_SOCKET) { return; } SetNonblocking(true, s); Attach(s); } return; } #endif #endif if (GetSocket() == INVALID_SOCKET) { SOCKET s = CreateSocket(AF_INET, SOCK_DGRAM, "udp"); if (s == INVALID_SOCKET) { return; } SetNonblocking(true, s); Attach(s); } }
void UdpSocket::SetMulticastLoop(bool x) { if (GetSocket() == INVALID_SOCKET) { CreateConnection(); } #ifdef ENABLE_IPV6 #ifdef IPPROTO_IPV6 if (IsIpv6()) { int val = x ? 1 : 0; if (setsockopt(GetSocket(), IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (char *)&val, sizeof(int)) == -1) { Handler().LogError(this, "SetMulticastLoop(ipv6)", Errno, StrError(Errno), LOG_LEVEL_WARNING); } return; } #endif #endif int val = x ? 1 : 0; if (setsockopt(GetSocket(), SOL_IP, IP_MULTICAST_LOOP, (char *)&val, sizeof(int)) == -1) { Handler().LogError(this, "SetMulticastLoop(ipv4)", Errno, StrError(Errno), LOG_LEVEL_WARNING); } }
int UdpSocket::Bind(const std::string& intf, port_t &port, int range) { #ifdef ENABLE_IPV6 #ifdef IPPROTO_IPV6 if (IsIpv6()) { Ipv6Address ad(intf, port); if (ad.IsValid()) { int n = Bind(ad, range); if (m_bind_ok) port = m_port; return n; } SetCloseAndDelete(); return -1; } #endif #endif Ipv4Address ad(intf, port); if (ad.IsValid()) { int n = Bind(ad, range); if (m_bind_ok) port = m_port; return n; } SetCloseAndDelete(); return -1; }
/** Returns local ipv6 address as text for bound socket file descriptor. */ std::string Socket::GetSockAddress6() { if (IsIpv6()) { struct sockaddr_in6 sa; socklen_t sockaddr_length = sizeof(struct sockaddr_in6); if (getsockname(GetSocket(), (struct sockaddr *)&sa, (socklen_t*)&sockaddr_length) == -1) memset(&sa, 0, sizeof(sa)); Ipv6Address addr( sa ); return addr.Convert(); } return ""; }
int SctpSocket::Bind(const std::string& a,port_t p) { #ifdef ENABLE_IPV6 #ifdef IPPROTO_IPV6 if (IsIpv6()) { Ipv6Address ad(a, p); return Bind(ad); } #endif #endif Ipv4Address ad(a, p); return Bind(ad); }
/** Returns local ipv6 address for bound socket file descriptor. */ struct in6_addr Socket::GetSockIP6() { if (IsIpv6()) { struct sockaddr_in6 sa; socklen_t sockaddr_length = sizeof(struct sockaddr_in6); if (getsockname(GetSocket(), (struct sockaddr *)&sa, (socklen_t*)&sockaddr_length) == -1) memset(&sa, 0, sizeof(sa)); return sa.sin6_addr; } struct in6_addr a; memset(&a, 0, sizeof(a)); return a; }
int UdpSocket::Bind(port_t &port, int range) { #ifdef ENABLE_IPV6 #ifdef IPPROTO_IPV6 if (IsIpv6()) { Ipv6Address ad(port); return Bind(ad, range); } #endif #endif Ipv4Address ad(port); return Bind(ad, range); }
void UdpSocket::SetMulticastHops(int hops) { if (GetSocket() == INVALID_SOCKET) { CreateConnection(); } if (!IsIpv6()) { Handler().LogError(this, "SetMulticastHops", 0, "Ipv6 only", LOG_LEVEL_ERROR); return; } if (setsockopt(GetSocket(), IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *)&hops, sizeof(int)) == -1) { Handler().LogError(this, "SetMulticastHops", Errno, StrError(Errno), LOG_LEVEL_WARNING); } }
bool TcpSocket::Open(const std::string &host,port_t port) { #ifdef ENABLE_IPV6 #ifdef IPPROTO_IPV6 if (IsIpv6()) { #ifdef ENABLE_RESOLVER if (!Handler().ResolverEnabled() || Utility::isipv6(host) ) { #endif in6_addr a; if (!Utility::u2ip(host, a)) { SetCloseAndDelete(); return false; } Ipv6Address ad(a, port); Ipv6Address local; return Open(ad, local); #ifdef ENABLE_RESOLVER } m_resolver_id = Resolve6(host, port); return true; #endif } #endif #endif #ifdef ENABLE_RESOLVER if (!Handler().ResolverEnabled() || Utility::isipv4(host) ) { #endif ipaddr_t l; if (!Utility::u2ip(host,l)) { SetCloseAndDelete(); return false; } Ipv4Address ad(l, port); Ipv4Address local; return Open(ad, local); #ifdef ENABLE_RESOLVER } // resolve using async resolver thread m_resolver_id = Resolve(host, port); return true; #endif }
/** Returns local ipv4 address as text for bound socket file descriptor. */ std::string Socket::GetSockAddress() { #ifdef ENABLE_IPV6 #ifdef IPPROTO_IPV6 if (IsIpv6()) { return ""; } #endif #endif struct sockaddr_in sa; socklen_t sockaddr_length = sizeof(struct sockaddr_in); if (getsockname(GetSocket(), (struct sockaddr *)&sa, (socklen_t*)&sockaddr_length) == -1) memset(&sa, 0, sizeof(sa)); Ipv4Address addr( sa ); return addr.Convert(); }
/** Returns local ipv4 address for bound socket file descriptor. */ ipaddr_t Socket::GetSockIP4() { #ifdef ENABLE_IPV6 #ifdef IPPROTO_IPV6 if (IsIpv6()) { return 0; } #endif #endif struct sockaddr_in sa; socklen_t sockaddr_length = sizeof(struct sockaddr_in); if (getsockname(GetSocket(), (struct sockaddr *)&sa, (socklen_t*)&sockaddr_length) == -1) memset(&sa, 0, sizeof(sa)); ipaddr_t a; memcpy(&a, &sa.sin_addr, 4); return a; }
int UdpSocket::GetMulticastHops() { if (GetSocket() == INVALID_SOCKET) { CreateConnection(); } if (!IsIpv6()) { Handler().LogError(this, "SetMulticastHops", 0, "Ipv6 only", LOG_LEVEL_ERROR); return -1; } int hops = 0; socklen_t size = sizeof(int); if (getsockopt(GetSocket(), IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *)&hops, &size) == -1) { Handler().LogError(this, "GetMulticastHops", Errno, StrError(Errno), LOG_LEVEL_WARNING); } return hops; }
/** Returns local port number for bound socket file descriptor. */ port_t Socket::GetSockPort() { #ifdef ENABLE_IPV6 #ifdef IPPROTO_IPV6 if (IsIpv6()) { struct sockaddr_in6 sa; socklen_t sockaddr_length = sizeof(struct sockaddr_in6); if (getsockname(GetSocket(), (struct sockaddr *)&sa, (socklen_t*)&sockaddr_length) == -1) memset(&sa, 0, sizeof(sa)); return ntohs(sa.sin6_port); } #endif #endif struct sockaddr_in sa; socklen_t sockaddr_length = sizeof(struct sockaddr_in); if (getsockname(GetSocket(), (struct sockaddr *)&sa, (socklen_t*)&sockaddr_length) == -1) memset(&sa, 0, sizeof(sa)); return ntohs(sa.sin_port); }
int UdpSocket::Bind(port_t &port, int range) { #ifdef ENABLE_IPV6 #ifdef IPPROTO_IPV6 if (IsIpv6()) { Ipv6Address ad(port); int n = Bind(ad, range); if (m_bind_ok) port = m_port; return n; } #endif #endif Ipv4Address ad(port); int n = Bind(ad, range); if (m_bind_ok) port = m_port; return n; }
/** send to specified address */ void UdpSocket::SendToBuf(const std::string& h, port_t p, const char *data, int len, int flags) { #ifdef ENABLE_IPV6 #ifdef IPPROTO_IPV6 if (IsIpv6()) { Ipv6Address ad(h, p); if (ad.IsValid()) { SendToBuf(ad, data, len, flags); } return; } #endif #endif Ipv4Address ad(h, p); if (ad.IsValid()) { SendToBuf(ad, data, len, flags); } }
bool UdpSocket::Open(const std::string& host, port_t port) { #ifdef ENABLE_IPV6 #ifdef IPPROTO_IPV6 if (IsIpv6()) { Ipv6Address ad(host, port); if (ad.IsValid()) { return Open(ad); } return false; } #endif #endif Ipv4Address ad(host, port); if (ad.IsValid()) { return Open(ad); } return false; }
void UdpSocket::DropMulticastMembership(const std::string& group, const std::string& local_if, int if_index) { if (GetSocket() == INVALID_SOCKET) { CreateConnection(); } #ifdef ENABLE_IPV6 #ifdef IPPROTO_IPV6 if (IsIpv6()) { struct ipv6_mreq x; struct in6_addr addr; if (Utility::u2ip( group, addr )) { x.ipv6mr_multiaddr = addr; x.ipv6mr_interface = if_index; if (setsockopt(GetSocket(), IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, (char *)&x, sizeof(struct ipv6_mreq)) == -1) { Handler().LogError(this, "DropMulticastMembership(ipv6)", Errno, StrError(Errno), LOG_LEVEL_WARNING); } } return; } #endif #endif struct ip_mreq x; // ip_mreqn ipaddr_t addr; if (Utility::u2ip( group, addr )) { memcpy(&x.imr_multiaddr.s_addr, &addr, sizeof(addr)); Utility::u2ip( local_if, addr); memcpy(&x.imr_interface.s_addr, &addr, sizeof(addr)); // x.imr_ifindex = if_index; if (setsockopt(GetSocket(), SOL_IP, IP_DROP_MEMBERSHIP, (char *)&x, sizeof(struct ip_mreq)) == -1) { Handler().LogError(this, "DropMulticastMembership(ipv4)", Errno, StrError(Errno), LOG_LEVEL_WARNING); } } }
void UdpSocket::OnRead() { #ifdef ENABLE_IPV6 #ifdef IPPROTO_IPV6 if (IsIpv6()) { struct sockaddr_in6 sa; socklen_t sa_len = sizeof(sa); if (m_b_read_ts) { struct timeval ts; Utility::GetTime(&ts); #if !defined(LINUX) && !defined(MACOSX) int n = recvfrom(GetSocket(), m_ibuf, m_ibufsz, 0, (struct sockaddr *)&sa, &sa_len); #else int n = ReadTS(m_ibuf, m_ibufsz, (struct sockaddr *)&sa, sa_len, &ts); #endif if (n > 0) { this -> OnRawData(m_ibuf, n, (struct sockaddr *)&sa, sa_len, &ts); } else if (n == -1) { #ifdef _WIN32 if (Errno != WSAEWOULDBLOCK) #else if (Errno != EWOULDBLOCK) #endif Handler().LogError(this, "recvfrom", Errno, StrError(Errno), LOG_LEVEL_ERROR); } return; } int n = recvfrom(GetSocket(), m_ibuf, m_ibufsz, 0, (struct sockaddr *)&sa, &sa_len); int q = m_retries; // receive max 10 at one cycle while (n > 0) { if (sa_len != sizeof(sa)) { Handler().LogError(this, "recvfrom", 0, "unexpected address struct size", LOG_LEVEL_WARNING); } this -> OnRawData(m_ibuf, n, (struct sockaddr *)&sa, sa_len); if (!q--) break; // n = recvfrom(GetSocket(), m_ibuf, m_ibufsz, 0, (struct sockaddr *)&sa, &sa_len); } if (n == -1) { #ifdef _WIN32 if (Errno != WSAEWOULDBLOCK) #else if (Errno != EWOULDBLOCK) #endif Handler().LogError(this, "recvfrom", Errno, StrError(Errno), LOG_LEVEL_ERROR); } return; } #endif #endif struct sockaddr_in sa; socklen_t sa_len = sizeof(sa); if (m_b_read_ts) { struct timeval ts; Utility::GetTime(&ts); #if !defined(LINUX) && !defined(MACOSX) int n = recvfrom(GetSocket(), m_ibuf, m_ibufsz, 0, (struct sockaddr *)&sa, &sa_len); #else int n = ReadTS(m_ibuf, m_ibufsz, (struct sockaddr *)&sa, sa_len, &ts); #endif if (n > 0) { this -> OnRawData(m_ibuf, n, (struct sockaddr *)&sa, sa_len, &ts); } else if (n == -1) { #ifdef _WIN32 if (Errno != WSAEWOULDBLOCK) #else if (Errno != EWOULDBLOCK) #endif Handler().LogError(this, "recvfrom", Errno, StrError(Errno), LOG_LEVEL_ERROR); } return; } int n = recvfrom(GetSocket(), m_ibuf, m_ibufsz, 0, (struct sockaddr *)&sa, &sa_len); int q = m_retries; while (n > 0) { if (sa_len != sizeof(sa)) { Handler().LogError(this, "recvfrom", 0, "unexpected address struct size", LOG_LEVEL_WARNING); } this -> OnRawData(m_ibuf, n, (struct sockaddr *)&sa, sa_len); if (!q--) break; // n = recvfrom(GetSocket(), m_ibuf, m_ibufsz, 0, (struct sockaddr *)&sa, &sa_len); } if (n == -1) { #ifdef _WIN32 if (Errno != WSAEWOULDBLOCK) #else if (Errno != EWOULDBLOCK) #endif Handler().LogError(this, "recvfrom", Errno, StrError(Errno), LOG_LEVEL_ERROR); } }