mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-21 12:44:58 +02:00
Implemented IPv6 support.
This commit is contained in:
parent
3825e2902f
commit
c1a8576c5c
@ -25,31 +25,54 @@ void TCPClient::Start(void)
|
|||||||
|
|
||||||
void TCPClient::Connect(const string& hostname, unsigned short port)
|
void TCPClient::Connect(const string& hostname, unsigned short port)
|
||||||
{
|
{
|
||||||
hostent *hent;
|
m_Role = RoleOutbound;
|
||||||
sockaddr_in sin;
|
|
||||||
|
|
||||||
memset(&sin, 0, sizeof(sin));
|
stringstream s;
|
||||||
sin.sin_family = AF_INET;
|
s << port;
|
||||||
sin.sin_port = htons(port);
|
string strPort = s.str();
|
||||||
|
|
||||||
hent = gethostbyname(hostname.c_str());
|
addrinfo hints;
|
||||||
|
addrinfo *result;
|
||||||
|
|
||||||
if (hent != NULL)
|
memset(&hints, 0, sizeof(hints));
|
||||||
sin.sin_addr.s_addr = ((in_addr *)hent->h_addr_list[0])->s_addr;
|
hints.ai_family = AF_UNSPEC;
|
||||||
else
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
sin.sin_addr.s_addr = inet_addr(hostname.c_str());
|
hints.ai_protocol = IPPROTO_TCP;
|
||||||
|
|
||||||
int rc = connect(GetFD(), (sockaddr *)&sin, sizeof(sin));
|
int rc = getaddrinfo(hostname.c_str(), strPort.c_str(), &hints, &result);
|
||||||
|
|
||||||
#ifdef _WIN32
|
if (rc < 0) {
|
||||||
if (rc < 0 && WSAGetLastError() != WSAEWOULDBLOCK) {
|
|
||||||
#else /* _WIN32 */
|
|
||||||
if (rc < 0 && errno != EINPROGRESS) {
|
|
||||||
#endif /* _WIN32 */
|
|
||||||
HandleSocketError();
|
HandleSocketError();
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Role = RoleOutbound;
|
int fd = INVALID_SOCKET;
|
||||||
|
|
||||||
|
for (addrinfo *info = result; info != NULL; info = info->ai_next) {
|
||||||
|
fd = socket(info->ai_family, info->ai_socktype, info->ai_protocol);
|
||||||
|
|
||||||
|
if (fd == INVALID_SOCKET)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
SetFD(fd);
|
||||||
|
|
||||||
|
rc = connect(fd, info->ai_addr, info->ai_addrlen);
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
if (rc < 0 && WSAGetLastError() != WSAEWOULDBLOCK)
|
||||||
|
#else /* _WIN32 */
|
||||||
|
if (rc < 0 && errno != EINPROGRESS)
|
||||||
|
#endif /* _WIN32 */
|
||||||
|
continue;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fd == INVALID_SOCKET)
|
||||||
|
HandleSocketError();
|
||||||
|
|
||||||
|
freeaddrinfo(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
FIFO::Ptr TCPClient::GetSendQueue(void)
|
FIFO::Ptr TCPClient::GetSendQueue(void)
|
||||||
|
@ -37,7 +37,7 @@ void TCPServer::Listen(void)
|
|||||||
int TCPServer::ReadableEventHandler(const EventArgs& ea)
|
int TCPServer::ReadableEventHandler(const EventArgs& ea)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
sockaddr_in addr;
|
sockaddr_storage addr;
|
||||||
socklen_t addrlen = sizeof(addr);
|
socklen_t addrlen = sizeof(addr);
|
||||||
|
|
||||||
fd = accept(GetFD(), (sockaddr *)&addr, &addrlen);
|
fd = accept(GetFD(), (sockaddr *)&addr, &addrlen);
|
||||||
|
@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
void TCPSocket::MakeSocket(void)
|
void TCPSocket::MakeSocket(int family)
|
||||||
{
|
{
|
||||||
assert(GetFD() == INVALID_SOCKET);
|
assert(GetFD() == INVALID_SOCKET);
|
||||||
|
|
||||||
int fd = socket(AF_INET, SOCK_STREAM, 0);
|
int fd = socket(family, SOCK_STREAM, 0);
|
||||||
|
|
||||||
if (fd == INVALID_SOCKET) {
|
if (fd == INVALID_SOCKET) {
|
||||||
HandleSocketError();
|
HandleSocketError();
|
||||||
@ -17,118 +17,106 @@ void TCPSocket::MakeSocket(void)
|
|||||||
SetFD(fd);
|
SetFD(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TCPSocket::Bind(unsigned short port)
|
void TCPSocket::Bind(unsigned short port, int family)
|
||||||
{
|
{
|
||||||
Bind(NULL, port);
|
Bind(NULL, port, family);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TCPSocket::Bind(const char *hostname, unsigned short port)
|
void TCPSocket::Bind(const char *hostname, unsigned short port, int family)
|
||||||
{
|
{
|
||||||
|
stringstream s;
|
||||||
|
s << port;
|
||||||
|
string strPort = s.str();
|
||||||
|
|
||||||
|
addrinfo hints;
|
||||||
|
addrinfo *result;
|
||||||
|
|
||||||
|
memset(&hints, 0, sizeof(hints));
|
||||||
|
hints.ai_family = AF_UNSPEC;
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
hints.ai_protocol = IPPROTO_TCP;
|
||||||
|
hints.ai_flags = AI_PASSIVE;
|
||||||
|
|
||||||
|
if (getaddrinfo(hostname, strPort.c_str(), &hints, &result) < 0) {
|
||||||
|
HandleSocketError();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fd = INVALID_SOCKET;
|
||||||
|
|
||||||
|
for (addrinfo *info = result; info != NULL; info = info->ai_next) {
|
||||||
|
fd = socket(info->ai_family, info->ai_socktype, info->ai_protocol);
|
||||||
|
|
||||||
|
if (fd == INVALID_SOCKET)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
SetFD(fd);
|
||||||
|
|
||||||
|
const int optFalse = 0;
|
||||||
|
setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&optFalse, sizeof(optFalse));
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
const int optTrue = 1;
|
const int optTrue = 1;
|
||||||
setsockopt(GetFD(), SOL_SOCKET, SO_REUSEADDR, (char *)&optTrue, sizeof(optTrue));
|
setsockopt(GetFD(), SOL_SOCKET, SO_REUSEADDR, (char *)&optTrue, sizeof(optTrue));
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
sockaddr_in sin;
|
int rc = ::bind(fd, info->ai_addr, info->ai_addrlen);
|
||||||
memset(&sin, 0, sizeof(sin));
|
|
||||||
sin.sin_family = AF_INET;
|
|
||||||
sin.sin_addr.s_addr = hostname ? inet_addr(hostname) : htonl(INADDR_ANY);
|
|
||||||
sin.sin_port = htons(port);
|
|
||||||
|
|
||||||
if (::bind(GetFD(), (sockaddr *)&sin, sizeof(sin)) < 0)
|
|
||||||
HandleSocketError();
|
|
||||||
}
|
|
||||||
|
|
||||||
string TCPSocket::GetAddressFromSockaddr(sockaddr *address)
|
|
||||||
{
|
|
||||||
static char buffer[256];
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
DWORD BufferLength = sizeof(buffer);
|
if (rc < 0 && WSAGetLastError() != WSAEWOULDBLOCK)
|
||||||
|
|
||||||
socklen_t len;
|
|
||||||
if (address->sa_family == AF_INET)
|
|
||||||
len = sizeof(sockaddr_in);
|
|
||||||
else if (address->sa_family == AF_INET6)
|
|
||||||
len = sizeof(sockaddr_in6);
|
|
||||||
else {
|
|
||||||
assert(0);
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (WSAAddressToString(address, len, NULL, buffer, &BufferLength) != 0)
|
|
||||||
return string();
|
|
||||||
#else /* _WIN32 */
|
#else /* _WIN32 */
|
||||||
void *IpAddress;
|
if (rc < 0 && errno != EINPROGRESS)
|
||||||
|
|
||||||
if (address->sa_family == AF_INET)
|
|
||||||
IpAddress = &(((sockaddr_in *)address)->sin_addr);
|
|
||||||
else
|
|
||||||
IpAddress = &(((sockaddr_in6 *)address)->sin6_addr);
|
|
||||||
|
|
||||||
if (inet_ntop(address->sa_family, IpAddress, buffer, sizeof(buffer)) == NULL)
|
|
||||||
return string();
|
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
continue;
|
||||||
|
|
||||||
return buffer;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
unsigned short TCPSocket::GetPortFromSockaddr(sockaddr *address)
|
|
||||||
{
|
|
||||||
if (address->sa_family == AF_INET)
|
|
||||||
return htons(((sockaddr_in *)address)->sin_port);
|
|
||||||
else if (address->sa_family == AF_INET6)
|
|
||||||
return htons(((sockaddr_in6 *)address)->sin6_port);
|
|
||||||
else {
|
|
||||||
assert(0);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
bool TCPSocket::GetClientSockaddr(sockaddr_storage *address)
|
if (fd == INVALID_SOCKET)
|
||||||
{
|
|
||||||
socklen_t len = sizeof(*address);
|
|
||||||
|
|
||||||
if (getsockname(GetFD(), (sockaddr *)address, &len) < 0) {
|
|
||||||
HandleSocketError();
|
HandleSocketError();
|
||||||
|
|
||||||
return false;
|
freeaddrinfo(result);
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TCPSocket::GetPeerSockaddr(sockaddr_storage *address)
|
|
||||||
|
string TCPSocket::GetAddressFromSockaddr(sockaddr *address, socklen_t len)
|
||||||
{
|
{
|
||||||
socklen_t len = sizeof(*address);
|
char host[NI_MAXHOST];
|
||||||
|
char service[NI_MAXSERV];
|
||||||
|
|
||||||
if (getpeername(GetFD(), (sockaddr *)address, &len) < 0) {
|
if (getnameinfo(address, len, host, sizeof(host), service, sizeof(service), NI_NUMERICHOST | NI_NUMERICSERV) < 0)
|
||||||
HandleSocketError();
|
throw InvalidArgumentException(); /* TODO: throw proper exception */
|
||||||
|
|
||||||
return false;
|
stringstream s;
|
||||||
}
|
s << "[" << host << "]:" << service;
|
||||||
|
return s.str();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string TCPSocket::GetClientAddress(void)
|
string TCPSocket::GetClientAddress(void)
|
||||||
{
|
{
|
||||||
sockaddr_storage sin;
|
sockaddr_storage sin;
|
||||||
|
socklen_t len = sizeof(sin);
|
||||||
|
|
||||||
if (!GetClientSockaddr(&sin))
|
if (getsockname(GetFD(), (sockaddr *)&sin, &len) < 0) {
|
||||||
return "";
|
HandleSocketError();
|
||||||
|
|
||||||
return GetAddressFromSockaddr((sockaddr *)&sin);
|
return string();
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetAddressFromSockaddr((sockaddr *)&sin, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
string TCPSocket::GetPeerAddress(void)
|
string TCPSocket::GetPeerAddress(void)
|
||||||
{
|
{
|
||||||
sockaddr_storage sin;
|
sockaddr_storage sin;
|
||||||
|
socklen_t len = sizeof(sin);
|
||||||
|
|
||||||
if (!GetPeerSockaddr(&sin))
|
if (getpeername(GetFD(), (sockaddr *)&sin, &len) < 0) {
|
||||||
return "";
|
HandleSocketError();
|
||||||
|
|
||||||
return GetAddressFromSockaddr((sockaddr *)&sin);
|
return string();
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetAddressFromSockaddr((sockaddr *)&sin, len);
|
||||||
}
|
}
|
||||||
|
@ -7,17 +7,16 @@ namespace icinga
|
|||||||
class I2_BASE_API TCPSocket : public Socket
|
class I2_BASE_API TCPSocket : public Socket
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
static string GetAddressFromSockaddr(sockaddr *address);
|
static string GetAddressFromSockaddr(sockaddr *address, socklen_t len);
|
||||||
static unsigned short GetPortFromSockaddr(sockaddr *address);
|
|
||||||
|
void MakeSocket(int family);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef shared_ptr<TCPSocket> Ptr;
|
typedef shared_ptr<TCPSocket> Ptr;
|
||||||
typedef weak_ptr<TCPSocket> WeakPtr;
|
typedef weak_ptr<TCPSocket> WeakPtr;
|
||||||
|
|
||||||
void MakeSocket(void);
|
void Bind(unsigned short port, int family);
|
||||||
|
void Bind(const char *hostname, unsigned short port, int family);
|
||||||
void Bind(unsigned short port);
|
|
||||||
void Bind(const char *hostname, unsigned short port);
|
|
||||||
|
|
||||||
bool GetClientSockaddr(sockaddr_storage *address);
|
bool GetClientSockaddr(sockaddr_storage *address);
|
||||||
bool GetPeerSockaddr(sockaddr_storage *address);
|
bool GetPeerSockaddr(sockaddr_storage *address);
|
||||||
|
@ -16,8 +16,7 @@ void EndpointManager::AddListener(unsigned short port)
|
|||||||
JsonRpcServer::Ptr server = make_shared<JsonRpcServer>(m_SSLContext);
|
JsonRpcServer::Ptr server = make_shared<JsonRpcServer>(m_SSLContext);
|
||||||
RegisterServer(server);
|
RegisterServer(server);
|
||||||
|
|
||||||
server->MakeSocket();
|
server->Bind(port, AF_INET6);
|
||||||
server->Bind(port);
|
|
||||||
server->Listen();
|
server->Listen();
|
||||||
server->Start();
|
server->Start();
|
||||||
}
|
}
|
||||||
@ -25,7 +24,7 @@ void EndpointManager::AddListener(unsigned short port)
|
|||||||
void EndpointManager::AddConnection(string host, unsigned short port)
|
void EndpointManager::AddConnection(string host, unsigned short port)
|
||||||
{
|
{
|
||||||
stringstream s;
|
stringstream s;
|
||||||
s << "Adding new endpoint: " << host << ":" << port;
|
s << "Adding new endpoint: [" << host << "]:" << port;
|
||||||
Application::Log(s.str());
|
Application::Log(s.str());
|
||||||
|
|
||||||
JsonRpcEndpoint::Ptr endpoint = make_shared<JsonRpcEndpoint>();
|
JsonRpcEndpoint::Ptr endpoint = make_shared<JsonRpcEndpoint>();
|
||||||
|
@ -63,7 +63,6 @@ void JsonRpcEndpoint::Connect(string host, unsigned short port, shared_ptr<SSL_C
|
|||||||
m_PeerPort = port;
|
m_PeerPort = port;
|
||||||
|
|
||||||
JsonRpcClient::Ptr client = make_shared<JsonRpcClient>(RoleOutbound, sslContext);
|
JsonRpcClient::Ptr client = make_shared<JsonRpcClient>(RoleOutbound, sslContext);
|
||||||
client->MakeSocket();
|
|
||||||
client->Connect(host, port);
|
client->Connect(host, port);
|
||||||
client->Start();
|
client->Start();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user