Commit 0ca49482 authored by Jérome Perrin's avatar Jérome Perrin

Support IPv6

If address contain ":", it is interpreted as an ipv6
parent b5d8fe09
...@@ -72,39 +72,54 @@ socket_t ListenTask::waitConnection() ...@@ -72,39 +72,54 @@ socket_t ListenTask::waitConnection()
bool ListenTask::Listen(const string& address, int port) bool ListenTask::Listen(const string& address, int port)
{ {
// create a new socket
readSocket = socket(AF_INET, SOCK_STREAM, 0); bool is_ipv6 = address.find(":") != string::npos;
sockaddr_in addr4;
if (readSocket < 0) { sockaddr_in6 addr6;
Logger::error << "socket failed in " << __FUNCTION__ << "(" << __FILE__ << "@" << __LINE__ << ")" << " with " << errno_socket << " (" << strerror_socket(errno_socket) << ")" << endl;
return false;
}
// bind to an address or any address // bind to an address or any address
sockaddr_in addr;
if (address.empty()) { if (address.empty()) {
memset(&addr, 0, sizeof(addr)); memset(&addr4, 0, sizeof(addr4));
addr.sin_family = AF_INET; addr4.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY); addr4.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(port); addr4.sin_port = htons(port);
} else { } else {
if (is_ipv6) {
char straddr[INET6_ADDRSTRLEN];
memset(&addr6, 0, sizeof(addr6));
addr6.sin6_family = AF_INET6;
addr6.sin6_port = htons(port);
inet_pton(AF_INET6, address.c_str(), &(addr6.sin6_addr));
// resolve name Logger::debug << "Listening on ipv6 " << address << endl;
struct ::hostent * sheep = ::gethostbyname(address.c_str()); } else {
if (sheep == 0) { // resolve name
Logger::error << "cannot resolve hostname in " << __FUNCTION__ << "(" << __FILE__ << "@" << __LINE__ << ")" << " with " << errno_socket << " (" << strerror_socket(errno_socket) << ")" << endl; struct ::hostent * sheep = ::gethostbyname(address.c_str());
return false;
}
// bind socket to an address if (sheep == 0) {
memset(&addr, 0, sizeof(addr)); Logger::error << "cannot resolve hostname in " << __FUNCTION__ << "(" << __FILE__ << "@" << __LINE__ << ")" << " with " << errno_socket << " (" << strerror_socket(errno_socket) << ")" << endl;
return false;
}
// bind socket to an address
memset(&addr4, 0, sizeof(addr4));
addr4.sin_family = AF_INET;
memcpy(&(addr4.sin_addr.s_addr), sheep->h_addr, sheep->h_length);
Logger::debug << "Listening on ipv4 " << address << endl;
addr4.sin_port = htons(port);
}
addr.sin_family = AF_INET; }
memcpy(&(addr.sin_addr.s_addr), sheep->h_addr, sheep->h_length);
addr.sin_port = htons(port); // create a new socket
readSocket = socket(is_ipv6 ? AF_INET6 : AF_INET, SOCK_STREAM, 0);
if (readSocket < 0) {
Logger::error << "socket failed in " << __FUNCTION__ << "(" << __FILE__ << "@" << __LINE__ << ")" << " with " << errno_socket << " (" << strerror_socket(errno_socket) << ")" << endl;
return false;
} }
#if !defined(_MSC_VER) #if !defined(_MSC_VER)
...@@ -114,7 +129,13 @@ bool ListenTask::Listen(const string& address, int port) ...@@ -114,7 +129,13 @@ bool ListenTask::Listen(const string& address, int port)
return false; return false;
} }
#endif #endif
int res = ::bind(readSocket, (const sockaddr*)&addr, sizeof(addr));
int res;
if (is_ipv6) {
res = ::bind(readSocket, (const sockaddr*)&addr6, sizeof(addr6));
} else {
res = ::bind(readSocket, (const sockaddr*)&addr4, sizeof(addr4));
}
if (res < 0) { if (res < 0) {
#if defined(_MSC_VER) #if defined(_MSC_VER)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment