BIND 10 trac2215a, updated. ce48fb5bb08976aa1428b14e14048cc249784d50 add inlines to make networking and error code more portable

BIND 10 source code commits bind10-changes at lists.isc.org
Fri Aug 24 04:23:43 UTC 2012


The branch, trac2215a has been updated
       via  ce48fb5bb08976aa1428b14e14048cc249784d50 (commit)
      from  95aef4bb28052e55e96d1079d6472e36bceff7f3 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit ce48fb5bb08976aa1428b14e14048cc249784d50
Author: Francis Dupont <fdupont at isc.org>
Date:   Fri Aug 24 06:23:03 2012 +0200

    add inlines to make networking and error code more portable

-----------------------------------------------------------------------

Summary of changes:
 src/bin/resolver/tests/resolver_config_unittest.cc |   12 ++--
 src/bin/sockcreator/main.cc                        |    2 +-
 src/bin/sockcreator/sockcreator.cc                 |   21 +++---
 src/bin/sockcreator/sockcreator.h                  |    1 +
 src/bin/sockcreator/tests/sockcreator_tests.cc     |   30 ++++----
 src/lib/asiodns/tests/dns_server_unittest.cc       |   20 ++++--
 src/lib/asiodns/tests/dns_service_unittest.cc      |    4 +-
 src/lib/asiodns/udp_server.cc                      |    2 +
 src/lib/asiolink/io_address.cc                     |    3 +-
 src/lib/cache/tests/rrset_entry_unittest.cc        |    3 +
 src/lib/cc/session.cc                              |   32 ++++++++-
 src/lib/cc/tests/run_unittests.cc                  |   14 ++++
 src/lib/cc/tests/session_unittests.cc              |   32 +++++++++
 src/lib/config/ccsession.cc                        |    6 +-
 src/lib/config/module_spec.cc                      |    5 +-
 src/lib/dhcp/iface_mgr.cc                          |   35 +++++-----
 src/lib/dhcp/tests/iface_mgr_unittest.cc           |   24 ++++---
 src/lib/dns/masterload.cc                          |    5 +-
 src/lib/dns/rdata/in_1/a_1.cc                      |    6 +-
 src/lib/dns/rdata/in_1/aaaa_28.cc                  |    5 +-
 src/lib/log/compiler/message.cc                    |   12 ++--
 src/lib/log/message_reader.cc                      |    7 +-
 .../isc/util/cio/socketsessionreceiver_python.cc   |    4 +-
 src/lib/resolve/tests/recursive_query_unittest.cc  |   31 +++++----
 src/lib/server_common/socket_request.cc            |   19 ++---
 .../server_common/tests/socket_requestor_test.cc   |   41 ++++++-----
 .../util/{interprocess_sync_null.cc => error.h}    |   44 ++++++++----
 src/lib/util/io/socket.cc                          |    9 ++-
 src/lib/util/io/socket_share.cc                    |   14 ++--
 src/lib/util/io/socketsession.cc                   |   45 +++++++-----
 src/lib/util/networking.h                          |   73 ++++++++++++++++++++
 src/lib/util/tests/socket_share_tests.cc           |    7 +-
 src/lib/util/tests/socketsession_unittest.cc       |   52 ++++++++------
 src/lib/util/unittests/fork.cc                     |    2 +-
 34 files changed, 429 insertions(+), 193 deletions(-)
 copy src/lib/util/{interprocess_sync_null.cc => error.h} (61%)
 create mode 100644 src/lib/util/networking.h

-----------------------------------------------------------------------
diff --git a/src/bin/resolver/tests/resolver_config_unittest.cc b/src/bin/resolver/tests/resolver_config_unittest.cc
index c89f9d7..26cd2e2 100644
--- a/src/bin/resolver/tests/resolver_config_unittest.cc
+++ b/src/bin/resolver/tests/resolver_config_unittest.cc
@@ -19,7 +19,6 @@
 #include <netinet/in.h>
 #include <netdb.h>
 
-#include <cerrno>
 #include <cstring>
 #include <string>
 
@@ -46,6 +45,8 @@
 
 #include <resolver/resolver.h>
 
+#include <util/networking.h>
+
 #include <dns/tests/unittest_util.h>
 #include <testutils/srv_test.h>
 #include <testutils/mockups.h>
@@ -62,6 +63,7 @@ using namespace isc::testutils;
 using namespace isc::asiodns;
 using namespace isc::asiolink;
 using namespace isc::server_common;
+using namespace isc::util;
 using isc::UnitTestUtil;
 
 namespace {
@@ -197,7 +199,7 @@ private:
 struct ScopedSocket : public boost::noncopyable {
 public:
     ScopedSocket(socket_type sd) : sd_(sd) {}
-    ~ScopedSocket() { close(sd_); }
+    ~ScopedSocket() { closesocket(sd_); }
 private:
     const socket_type sd_;
 };
@@ -219,12 +221,12 @@ createSocket(const char* address, const char* port) {
     const int s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
     if (s == -1) {
         isc_throw(TestConfigError, "socket system call failed: " <<
-                  strerror(errno));
+                  strneterror());
     }
     if (bind(s, res->ai_addr, res->ai_addrlen) == -1) {
-        close(s);
+        closesocket(s);
         isc_throw(TestConfigError, "bind system call failed: " <<
-                  strerror(errno));
+                  strneterror());
     }
     return (s);
 }
diff --git a/src/bin/sockcreator/main.cc b/src/bin/sockcreator/main.cc
index 2f6832e..618aff2 100644
--- a/src/bin/sockcreator/main.cc
+++ b/src/bin/sockcreator/main.cc
@@ -24,7 +24,7 @@ main() {
      * but ability to bind ports? It would be nice.
      */
     try {
-        run(STDIN_FILENO, STDOUT_FILENO, getSock, isc::util::io::send_socket, close);
+        run(STDIN_FILENO, STDOUT_FILENO, getSock, isc::util::io::send_socket, isc::util::closesocket);
     } catch (const SocketCreatorError& ec) {
         return (ec.getExitCode());
     }
diff --git a/src/bin/sockcreator/sockcreator.cc b/src/bin/sockcreator/sockcreator.cc
index 205795b..7ddc9ec 100644
--- a/src/bin/sockcreator/sockcreator.cc
+++ b/src/bin/sockcreator/sockcreator.cc
@@ -14,10 +14,10 @@
 
 #include "sockcreator.h"
 
+#include <util/networking.h>
 #include <util/io/socket.h>
 #include <util/io/sockaddr_util.h>
 
-#include <cerrno>
 #include <string.h>
 
 #include <unistd.h>
@@ -25,6 +25,7 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 
+using namespace isc::util;
 using namespace isc::util::io;
 using namespace isc::util::io::internal;
 using namespace isc::socket_creator;
@@ -176,7 +177,7 @@ handleRequest(const socket_type input_sd, const socket_type output_sd,
         writeMessage(output_sd, error_message, sizeof(error_message));
 
         // ...and append the reason code to the error message
-        const int error_number = errno;
+        const int error_number = getneterror();
         writeMessage(output_sd, &error_number, sizeof(error_number));
     }
 }
@@ -191,22 +192,24 @@ mtu(socket_type s) {
 #ifdef IPV6_USE_MIN_MTU        /* RFC 3542, not too common yet*/
     const int on(1);
     // use minimum MTU
-    if (setsockopt(s, IPPROTO_IPV6, IPV6_USE_MIN_MTU, &on, sizeof(on)) < 0) {
+    if (setsockopt(s, IPPROTO_IPV6, IPV6_USE_MIN_MTU,
+                   (char *)&on, sizeof(on)) < 0) {
         return (false);
     }
 #else // Try the following as fallback
 #ifdef IPV6_MTU
     // Use minimum MTU on systems that don't have the IPV6_USE_MIN_MTU
     const int mtu = 1280;
-    if (setsockopt(s, IPPROTO_IPV6, IPV6_MTU, &mtu, sizeof(mtu)) < 0) {
+    if (setsockopt(s, IPPROTO_IPV6, IPV6_MTU,
+                   (char *)&mtu, sizeof(mtu)) < 0) {
         return (false);
     }
 #endif
 #if defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DONT)
     // Turn off Path MTU discovery on IPv6/UDP sockets.
     const int action = IPV6_PMTUDISC_DONT;
-    if (setsockopt(s, IPPROTO_IPV6, IPV6_MTU_DISCOVER, &action,
-                   sizeof(action)) < 0) {
+    if (setsockopt(s, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
+                   (char *)&action, sizeof(action)) < 0) {
 
         return (false);
     }
@@ -247,13 +250,15 @@ getSock(const int type, struct sockaddr* bind_addr, bool* bind_failed,
         return (invalid_socket);
     }
     const int on = 1;
-    if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) {
+    if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
+                   (char *)&on, sizeof(on)) == socket_error_retval) {
         // This is part of the binding process, so it's a bind error
 	*bind_failed = true;
         return (maybeClose(false, sock, close_fun));
     }
     if (bind_addr->sa_family == AF_INET6 &&
-        setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) == -1) {
+        setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY,
+                   (char *)&on, sizeof(on)) == socket_error_retval) {
         // This is part of the binding process, so it's a bind error
 	*bind_failed = true;
         return (maybeClose(false, sock, close_fun));
diff --git a/src/bin/sockcreator/sockcreator.h b/src/bin/sockcreator/sockcreator.h
index 0aa48f3..8d94a2e 100644
--- a/src/bin/sockcreator/sockcreator.h
+++ b/src/bin/sockcreator/sockcreator.h
@@ -21,6 +21,7 @@
 #ifndef __SOCKCREATOR_H
 #define __SOCKCREATOR_H 1
 
+#include <util/networking.h>
 #include <util/io/socket_share.h>
 #include <exceptions/exceptions.h>
 
diff --git a/src/bin/sockcreator/tests/sockcreator_tests.cc b/src/bin/sockcreator/tests/sockcreator_tests.cc
index 64b3774..695c9ea 100644
--- a/src/bin/sockcreator/tests/sockcreator_tests.cc
+++ b/src/bin/sockcreator/tests/sockcreator_tests.cc
@@ -14,6 +14,7 @@
 
 #include "../sockcreator.h"
 
+#include <util/networking.h>
 #include <util/unittests/fork.h>
 #include <util/io/socket.h>
 
@@ -27,9 +28,9 @@
 
 #include <iostream>
 #include <cstring>
-#include <cerrno>
 
 using namespace isc::socket_creator;
+using namespace isc::util;
 using namespace isc::util::unittests;
 using namespace isc::util::io;
 
@@ -87,11 +88,11 @@ udpCheck(const socket_type socknum) {
 
     // Send the packet to ourselves and check we receive it.
     ASSERT_EQ(5, sendto(socknum, "test", 5, 0, addr_ptr, sizeof(addr))) <<
-        "Send failed with error " << strerror(errno) << " on socket " <<
+        "Send failed with error " << strneterror() << " on socket " <<
         socknum;
     char buffer[5];
     ASSERT_EQ(5, recv(socknum, buffer, 5, 0)) <<
-        "Recv failed with error " << strerror(errno) << " on socket " <<
+        "Recv failed with error " << strneterror() << " on socket " <<
         socknum;
     EXPECT_STREQ("test", buffer);
 }
@@ -116,15 +117,15 @@ void addressFamilySpecificCheck(const sockaddr_in6*, const socket_type socknum,
 {
     int options;
     socklen_t len = sizeof(options);
-    EXPECT_EQ(0, getsockopt(socknum, IPPROTO_IPV6, IPV6_V6ONLY, &options,
-                            &len));
+    EXPECT_EQ(0, getsockopt(socknum, IPPROTO_IPV6, IPV6_V6ONLY,
+                            (char *)&options, &len));
     EXPECT_NE(0, options);
     if (s_type == SOCK_DGRAM) {
     // Some more checks for UDP - MTU
 #ifdef IPV6_USE_MIN_MTU        /* RFC 3542, not too common yet*/
         // use minimum MTU
         EXPECT_EQ(0, getsockopt(socknum, IPPROTO_IPV6, IPV6_USE_MIN_MTU,
-                                &options, &len)) << strerror(errno);
+                                (char *)&options, &len)) << strneterror();
         EXPECT_NE(0, options);
 #else
         // We do not check for the IPV6_MTU, because while setting works (eg.
@@ -136,7 +137,7 @@ void addressFamilySpecificCheck(const sockaddr_in6*, const socket_type socknum,
 #if defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DONT)
         // Turned off Path MTU discovery on IPv6/UDP sockets?
         EXPECT_EQ(0, getsockopt(socknum, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
-                                &options, &len)) << strerror(errno);
+                                (char *)&options, &len)) << strneterror();
         EXPECT_EQ(IPV6_PMTUDISC_DONT, options);
 #endif
 #endif
@@ -171,7 +172,7 @@ void testAnyCreate(int s_type, socket_check_t socket_check) {
                                        sizeof(addr), closeIgnore);
     ASSERT_NE(socket, invalid_socket) <<
         "Couldn't create socket: failed with " <<
-        "return code " << socket << " and error " << strerror(errno);
+        "return code " << socket << " and error " << strneterror();
 
     // Perform socket-type-specific testing.
     socket_check(socket);
@@ -179,14 +180,15 @@ void testAnyCreate(int s_type, socket_check_t socket_check) {
     // Do address-family-independent
     int options;
     socklen_t len = sizeof(options);
-    EXPECT_EQ(0, getsockopt(socket, SOL_SOCKET, SO_REUSEADDR, &options, &len));
+    EXPECT_EQ(0, getsockopt(socket, SOL_SOCKET, SO_REUSEADDR,
+                            (char *)&options, &len));
     EXPECT_NE(0, options);
 
     // ...and the address-family specific tests.
     addressFamilySpecificCheck(&addr, socket, s_type);
 
     // Tidy up and exit.
-    EXPECT_EQ(0, close(socket));
+    EXPECT_EQ(0, closesocket(socket));
 }
 
 
@@ -213,7 +215,7 @@ bool close_called(false);
 // called, you can use the close_called variable. But set it to false before the
 // test.
 int closeCall(socket_type socket) {
-    close(socket);
+    closesocket(socket);
     close_called = true;
     return (0);
 }
@@ -300,7 +302,7 @@ getSockDummy(const int type, struct sockaddr* addr, bool* bf,
     // The port of 0xbbbb means bind should fail and 0xcccc means
     // socket should fail.
     if (port != 0xffff) {
-        errno = 0;
+        setneterror(0);
         if (port == 0xbbbb) {
             *bf = true;
             return (invalid_socket);
@@ -356,8 +358,8 @@ void runTest(const char* input_data, const size_t input_size,
     }
 
     // Close the pipes
-    close(input_sd);
-    close(output_sd);
+    closesocket(input_sd);
+    closesocket(output_sd);
 
     // Check the subprocesses say everything is OK too
     EXPECT_TRUE(process_ok(input));
diff --git a/src/lib/asiodns/tests/dns_server_unittest.cc b/src/lib/asiodns/tests/dns_server_unittest.cc
index c84a32e..e79710e 100644
--- a/src/lib/asiodns/tests/dns_server_unittest.cc
+++ b/src/lib/asiodns/tests/dns_server_unittest.cc
@@ -23,9 +23,10 @@
 #include <asiodns/tcp_server.h>
 #include <asiodns/dns_answer.h>
 #include <asiodns/dns_lookup.h>
+#include <util/error.h>
+#include <util/networking.h>
 #include <string>
 #include <cstring>
-#include <cerrno>
 #include <csignal>
 #include <unistd.h> //for alarm
 
@@ -439,21 +440,28 @@ private:
         }
 
         socket_type sock;
+#ifndef _WIN32
         const int on(1);
+#endif
         // Go as far as you can and stop on failure
         // Create the socket
         // set the options
         // and bind it
         sock = socket(res->ai_family, res->ai_socktype,	res->ai_protocol);
         const bool failed(sock == invalid_socket ||
-                          setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on,
-                                     sizeof(on)) == -1 ||
+#ifndef _WIN32
+                          setsockopt(sock,
+                                     SOL_SOCKET,
+                                     SO_REUSEADDR,
+                                     (char *) &on,
+                                     sizeof(on)) == socket_error_retval ||
+#endif
                           bind(sock, res->ai_addr, res->ai_addrlen) == -1);
         // No matter if it succeeded or not, free the address info
         freeaddrinfo(res);
         if (failed) {
             if (sock != invalid_socket) {
-                close(sock);
+                isc::util::closesocket(sock);
             }
             return (invalid_socket);
         } else {
@@ -464,13 +472,13 @@ protected:
     // Using SetUp here so we can ASSERT_*
     void SetUp() {
         const socket_type socketUDP(getSocket(SOCK_DGRAM));
-        ASSERT_NE(invalid_socket, socketUDP) << strerror(errno);
+        ASSERT_NE(invalid_socket, socketUDP) << isc::util::strneterror();
         this->udp_server_ = new UDPServerClass(this->service,
                                                socketUDP, AF_INET6,
                                                this->checker_, this->lookup_,
                                                this->answer_);
         const socket_type socketTCP(getSocket(SOCK_STREAM));
-        ASSERT_NE(invalid_socket, socketTCP) << strerror(errno);
+        ASSERT_NE(invalid_socket, socketTCP) << isc::util::strneterror();
         this->tcp_server_ = new TCPServer(this->service,
                                           socketTCP, AF_INET6,
                                           this->checker_, this->lookup_,
diff --git a/src/lib/asiodns/tests/dns_service_unittest.cc b/src/lib/asiodns/tests/dns_service_unittest.cc
index 9b5e3c5..db1062c 100644
--- a/src/lib/asiodns/tests/dns_service_unittest.cc
+++ b/src/lib/asiodns/tests/dns_service_unittest.cc
@@ -21,6 +21,8 @@
 #include <asiolink/asiolink.h>
 #include <asiodns/asiodns.h>
 
+#include <util/networking.h>
+
 #include <boost/scoped_ptr.hpp>
 #include <boost/lexical_cast.hpp>
 
@@ -182,7 +184,7 @@ getSocketSD(int family, const char* const address, const char* const port) {
     }
     if (error != 0) {
         if (s != invalid_socket) {
-            close(s);
+            isc::util::closesocket(s);
         }
         isc_throw(isc::Unexpected, "failed to open test socket");
     }
diff --git a/src/lib/asiodns/udp_server.cc b/src/lib/asiodns/udp_server.cc
index b0fd353..d847a8a 100644
--- a/src/lib/asiodns/udp_server.cc
+++ b/src/lib/asiodns/udp_server.cc
@@ -70,7 +70,9 @@ struct UDPServer::Data {
         // otherwise ASIO will bind to both
         udp proto = addr.is_v4() ? udp::v4() : udp::v6();
         socket_.reset(new udp::socket(io_service, proto));
+#ifndef _WIN32
         socket_->set_option(socket_base::reuse_address(true));
+#endif
         if (addr.is_v6()) {
             socket_->set_option(asio::ip::v6_only(true));
         }
diff --git a/src/lib/asiolink/io_address.cc b/src/lib/asiolink/io_address.cc
index 832452c..9442a60 100644
--- a/src/lib/asiolink/io_address.cc
+++ b/src/lib/asiolink/io_address.cc
@@ -22,6 +22,7 @@
 #include <asio.hpp>
 
 #include <exceptions/exceptions.h>
+#include <util/networking.h>
 #include <asiolink/io_address.h>
 #include <asiolink/io_error.h>
 #include <boost/static_assert.hpp>
@@ -72,7 +73,7 @@ IOAddress::from_bytes(short family, const uint8_t* data) {
 
     BOOST_STATIC_ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN);
     char addr_str[INET6_ADDRSTRLEN];
-    inet_ntop(family, data, addr_str, INET6_ADDRSTRLEN);
+    isc::util::inetntop(family, data, addr_str, INET6_ADDRSTRLEN);
     return IOAddress(string(addr_str));
 }
 
diff --git a/src/lib/cache/tests/rrset_entry_unittest.cc b/src/lib/cache/tests/rrset_entry_unittest.cc
index c7c3c6e..354e42b 100644
--- a/src/lib/cache/tests/rrset_entry_unittest.cc
+++ b/src/lib/cache/tests/rrset_entry_unittest.cc
@@ -14,6 +14,9 @@
 
 #include <config.h>
 #include <string>
+#ifdef _WIN32
+#include <ctime>
+#endif
 #include <gtest/gtest.h>
 #include <cache/cache_entry_key.h>
 #include <cache/rrset_entry.h>
diff --git a/src/lib/cc/session.cc b/src/lib/cc/session.cc
index 6e1ef54..103942c 100644
--- a/src/lib/cc/session.cc
+++ b/src/lib/cc/session.cc
@@ -35,7 +35,13 @@
 #include <iostream>
 #include <sstream>
 
+#ifdef _WIN32
+#define DONT_USE_LOCAL_SOCKET
+#endif
+
+#ifndef DONT_USE_LOCAL_SOCKET
 #include <sys/un.h>
+#endif
 
 #include <boost/bind.hpp>
 #include <boost/optional.hpp>
@@ -101,7 +107,11 @@ private:
 
 private:
     io_service& io_service_;
+#ifndef DONT_USE_LOCAL_SOCKET
     asio::local::stream_protocol::socket socket_;
+#else
+    asio::ip::tcp::socket socket_;
+#endif
     uint32_t data_length_;
     boost::function<void()> user_handler_;
     asio::error_code error_;
@@ -122,12 +132,30 @@ void
 SessionImpl::establish(const char& socket_file) {
     try {
         LOG_DEBUG(logger, DBG_TRACE_BASIC, CC_ESTABLISH).arg(&socket_file);
-        socket_.connect(asio::local::stream_protocol::endpoint(&socket_file),
-                        error_);
+#ifndef DONT_USE_LOCAL_SOCKET
+        asio::local::stream_protocol::endpoint ep(&socket_file);
+#else
+        const std::string spec(&socket_file);
+        asio::ip::address addr;
+        if (spec.find("v4_") == 0)
+            addr = asio::ip::address_v4::loopback();
+        else if (spec.find("v6_") == 0)
+            addr = asio::ip::address_v6::loopback();
+        else {
+             isc_throw(SessionError, "bad endpoint: " << spec);
+        }
+        uint16_t port = boost::lexical_cast<uint16_t>(spec.substr(3));
+        asio::ip::tcp::endpoint ep(addr, port);
+#endif
+        socket_.connect(ep, error_);
         LOG_DEBUG(logger, DBG_TRACE_BASIC, CC_ESTABLISHED);
     } catch(const asio::system_error& se) {
         LOG_FATAL(logger, CC_CONN_ERROR).arg(se.what());
         isc_throw(SessionError, se.what());
+#ifdef DONT_USE_LOCAL_SOCKET
+    } catch(const boost::bad_lexical_cast&) {
+        isc_throw(SessionError, "bad port");
+#endif
     }
     if (error_) {
         LOG_FATAL(logger, CC_NO_MSGQ).arg(error_.message());
diff --git a/src/lib/cc/tests/run_unittests.cc b/src/lib/cc/tests/run_unittests.cc
index 299bd96..e55e281 100644
--- a/src/lib/cc/tests/run_unittests.cc
+++ b/src/lib/cc/tests/run_unittests.cc
@@ -12,6 +12,12 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
+#include <config.h>
+
+#ifdef _WIN32
+#include <winsock2.h>
+#endif
+
 #include <gtest/gtest.h>
 #include <util/unittests/run_all.h>
 #include <log/logger_support.h>
@@ -22,5 +28,13 @@ main(int argc, char* argv[]) {
 
     isc::log::initLogger();
 
+#ifdef _WIN32
+    WSADATA wsaData;
+    WSAStartup(MAKEWORD(2,2), &wsaData);
+    int ret = isc::util::unittests::run_all();
+    WSACleanup();
+    return (ret);
+#else
     return (isc::util::unittests::run_all());
+#endif
 }
diff --git a/src/lib/cc/tests/session_unittests.cc b/src/lib/cc/tests/session_unittests.cc
index 6152b50..5b5a645 100644
--- a/src/lib/cc/tests/session_unittests.cc
+++ b/src/lib/cc/tests/session_unittests.cc
@@ -28,6 +28,10 @@
 #include <cc/data.h>
 #include <session_unittests_config.h>
 
+#ifdef _WIN32
+#define DONT_USE_LOCAL_SOCKET
+#endif
+
 using namespace asio::detail;
 using namespace isc::cc;
 
@@ -63,10 +67,28 @@ class TestDomainSocket {
 public:
     TestDomainSocket(asio::io_service& io_service, const char* file) :
         io_service_(io_service),
+#ifndef DONT_USE_LOCAL_SOCKET
         ep_(file),
         acceptor_(io_service_, ep_),
+#else
+        acceptor_(io_service_),
+#endif
         socket_(io_service_)
     {
+#ifdef DONT_USE_LOCAL_SOCKET
+        std::string spec(file);
+        asio::ip::address addr;
+        if (spec.find("v4_") == 0)
+            addr = asio::ip::address_v4::loopback();
+        else if (spec.find("v6_") == 0)
+            addr = asio::ip::address_v6::loopback();
+        uint16_t port = boost::lexical_cast<uint16_t>(spec.substr(3));
+        ep_ = asio::ip::tcp::endpoint(addr, port);
+        acceptor_.open(ep_.protocol());
+        acceptor_.set_option(asio::socket_base::reuse_address(true));
+        acceptor_.bind(ep_);
+        acceptor_.listen(asio::socket_base::max_connections);
+#endif
         acceptor_.async_accept(socket_,
                                boost::bind(&TestDomainSocket::acceptHandler,
                                            this, _1));
@@ -74,7 +96,9 @@ public:
     
     ~TestDomainSocket() {
         socket_.close();
+#ifndef DONT_USE_LOCAL_SOCKET
         unlink(BIND10_TEST_SOCKET_FILE);
+#endif
     }
 
     void
@@ -116,9 +140,15 @@ public:
     
 private:
     asio::io_service& io_service_;
+#ifndef DONT_USE_LOCAL_SOCKET
     asio::local::stream_protocol::endpoint ep_;
     asio::local::stream_protocol::acceptor acceptor_;
     asio::local::stream_protocol::socket socket_;
+#else
+    asio::ip::tcp::endpoint ep_;
+    asio::ip::tcp::acceptor acceptor_;
+    asio::ip::tcp::socket socket_;
+#endif
     char data_buf[1024];
 };
 
@@ -127,7 +157,9 @@ protected:
     SessionTest() : sess(my_io_service), work(my_io_service) {
         // The TestDomainSocket is held as a 'new'-ed pointer,
         // so we can call unlink() first.
+#ifndef DONT_USE_LOCAL_SOCKET
         unlink(BIND10_TEST_SOCKET_FILE);
+#endif
         tds = new TestDomainSocket(my_io_service, BIND10_TEST_SOCKET_FILE);
     }
 
diff --git a/src/lib/config/ccsession.cc b/src/lib/config/ccsession.cc
index d4c6653..b1cbe69 100644
--- a/src/lib/config/ccsession.cc
+++ b/src/lib/config/ccsession.cc
@@ -21,7 +21,6 @@
 #include <ctype.h>
 
 #include <algorithm>
-#include <cerrno>
 #include <fstream>
 #include <iostream>
 #include <set>
@@ -35,6 +34,7 @@
 #include <module_spec.h>
 #include <cc/session.h>
 #include <exceptions/exceptions.h>
+#include <util/error.h>
 
 #include <config/config_log.h>
 #include <config/ccsession.h>
@@ -399,8 +399,8 @@ ModuleCCSession::readModuleSpecification(const std::string& filename) {
     // this file should be declared in a @something@ directive
     file.open(filename.c_str());
     if (!file) {
-        LOG_ERROR(config_logger, CONFIG_OPEN_FAIL).arg(filename).arg(strerror(errno));
-        isc_throw(CCSessionInitError, strerror(errno));
+        LOG_ERROR(config_logger, CONFIG_OPEN_FAIL).arg(filename).arg(isc::util::strerror());
+        isc_throw(CCSessionInitError, isc::util::strerror());
     }
 
     try {
diff --git a/src/lib/config/module_spec.cc b/src/lib/config/module_spec.cc
index da42a5e..e3caf19 100644
--- a/src/lib/config/module_spec.cc
+++ b/src/lib/config/module_spec.cc
@@ -15,10 +15,11 @@
 
 #include <config/module_spec.h>
 
+#include <util/error.h>
+
 #include <sstream>
 #include <iostream>
 #include <fstream>
-#include <cerrno>
 
 #include <boost/foreach.hpp>
 
@@ -314,7 +315,7 @@ moduleSpecFromFile(const std::string& file_name, const bool check)
     file.open(file_name.c_str());
     if (!file) {
         std::stringstream errs;
-        errs << "Error opening " << file_name << ": " << strerror(errno);
+        errs << "Error opening " << file_name << ": " << isc::util::strerror();
         isc_throw(ModuleSpecError, errs.str());
     }
 
diff --git a/src/lib/dhcp/iface_mgr.cc b/src/lib/dhcp/iface_mgr.cc
index ac738ac..d17c737 100644
--- a/src/lib/dhcp/iface_mgr.cc
+++ b/src/lib/dhcp/iface_mgr.cc
@@ -28,10 +28,12 @@
 #include <asiolink/udp_endpoint.h>
 #include <asiolink/io_error.h>
 #include <util/io/pktinfo_utilities.h>
+#include <util/networking.h>
 
 using namespace std;
 using namespace asio::detail;
 using namespace isc::asiolink;
+using namespace isc::util;
 using namespace isc::util::io::internal;
 
 namespace isc {
@@ -115,7 +117,7 @@ bool IfaceMgr::Iface::delSocket(socket_type sockfd) {
     list<SocketInfo>::iterator sock = sockets_.begin();
     while (sock!=sockets_.end()) {
         if (sock->sockfd_ == sockfd) {
-            close(sockfd);
+            closesocket(sockfd);
             sockets_.erase(sock);
             return (true); //socket found
         }
@@ -159,7 +161,7 @@ void IfaceMgr::closeSockets() {
         for (SocketCollection::iterator sock = iface->sockets_.begin();
              sock != iface->sockets_.end(); ++sock) {
             cout << "Closing socket " << sock->sockfd_ << endl;
-            close(sock->sockfd_);
+            closesocket(sock->sockfd_);
         }
         iface->sockets_.clear();
     }
@@ -304,7 +306,7 @@ bool IfaceMgr::openSockets6(const uint16_t port) {
             // on Linux.
             if ( !joinMulticast(sock, iface->getName(),
                                 string(ALL_DHCP_RELAY_AGENTS_AND_SERVERS))) {
-                close(sock);
+                closesocket(sock);
                 isc_throw(Unexpected, "Failed to join " << ALL_DHCP_RELAY_AGENTS_AND_SERVERS
                           << " multicast group.");
             }
@@ -533,7 +535,7 @@ socket_type IfaceMgr::openSocket4(Iface& iface,
     }
 
     if (bind(sock, (struct sockaddr *)&addr4, sizeof(addr4)) < 0) {
-        close(sock);
+        closesocket(sock);
         isc_throw(Unexpected, "Failed to bind socket " << sock << " to " << addr.toText()
                   << "/port=" << port);
     }
@@ -542,8 +544,9 @@ socket_type IfaceMgr::openSocket4(Iface& iface,
     // it will be difficult to undersand, where this packet came from
 #if defined(IP_PKTINFO)
     int flag = 1;
-    if (setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &flag, sizeof(flag)) != 0) {
-        close(sock);
+    if (setsockopt(sock, IPPROTO_IP, IP_PKTINFO,
+                   (char *)&flag, sizeof(flag)) != 0) {
+        closesocket(sock);
         isc_throw(Unexpected, "setsockopt: IP_PKTINFO: failed.");
     }
 #endif
@@ -591,27 +594,27 @@ socket_type IfaceMgr::openSocket6(Iface& iface,
     int flag = 1;
     if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
                    (char *)&flag, sizeof(flag)) < 0) {
-        close(sock);
+        closesocket(sock);
         isc_throw(Unexpected, "Can't set SO_REUSEADDR option on dhcpv6 socket.");
     }
 
     if (bind(sock, (struct sockaddr *)&addr6, sizeof(addr6)) < 0) {
-        close(sock);
+        closesocket(sock);
         isc_throw(Unexpected, "Failed to bind socket " << sock << " to " << addr.toText()
                   << "/port=" << port);
     }
 #ifdef IPV6_RECVPKTINFO
     // RFC3542 - a new way
     if (setsockopt(sock, IPPROTO_IPV6, IPV6_RECVPKTINFO,
-                   &flag, sizeof(flag)) != 0) {
-        close(sock);
+                   (char *)&flag, sizeof(flag)) != 0) {
+        closesocket(sock);
         isc_throw(Unexpected, "setsockopt: IPV6_RECVPKTINFO failed.");
     }
 #else
     // RFC2292 - an old way
     if (setsockopt(sock, IPPROTO_IPV6, IPV6_PKTINFO,
-                   &flag, sizeof(flag)) != 0) {
-        close(sock);
+                   (char *)&flag, sizeof(flag)) != 0) {
+        closesocket(sock);
         isc_throw(Unexpected, "setsockopt: IPV6_PKTINFO: failed.");
     }
 #endif
@@ -624,7 +627,7 @@ socket_type IfaceMgr::openSocket6(Iface& iface,
 
         if ( !joinMulticast( sock, iface.getName(),
                          string(ALL_DHCP_RELAY_AGENTS_AND_SERVERS) ) ) {
-            close(sock);
+            closesocket(sock);
             isc_throw(Unexpected, "Failed to join " << ALL_DHCP_RELAY_AGENTS_AND_SERVERS
                       << " multicast group.");
         }
@@ -654,7 +657,7 @@ IfaceMgr::joinMulticast(socket_type sock,
 
     mreq.ipv6mr_interface = if_nametoindex(ifname.c_str());
     if (setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP,
-                   &mreq, sizeof(mreq)) < 0) {
+                   (char *)&mreq, sizeof(mreq)) < 0) {
         cout << "Failed to join " << mcast << " multicast group." << endl;
         return (false);
     }
@@ -861,7 +864,7 @@ IfaceMgr::receive4(uint32_t timeout) {
         // nothing received and timeout has been reached
         return (Pkt4Ptr()); // NULL
     } else if (result < 0) {
-        cout << "Socket read error: " << strerror(errno) << endl;
+        cout << "Socket read error: " << strneterror() << endl;
 
         /// @todo: perhaps throw here?
         return (Pkt4Ptr()); // NULL
@@ -1029,7 +1032,7 @@ Pkt6Ptr IfaceMgr::receive6(uint32_t timeout) {
         // nothing received and timeout has been reached
         return (Pkt6Ptr()); // NULL
     } else if (result < 0) {
-        cout << "Socket read error: " << strerror(errno) << endl;
+        cout << "Socket read error: " << strneterror() << endl;
 
         /// @todo: perhaps throw here?
         return (Pkt6Ptr()); // NULL
diff --git a/src/lib/dhcp/tests/iface_mgr_unittest.cc b/src/lib/dhcp/tests/iface_mgr_unittest.cc
index df30578..c60994c 100644
--- a/src/lib/dhcp/tests/iface_mgr_unittest.cc
+++ b/src/lib/dhcp/tests/iface_mgr_unittest.cc
@@ -23,6 +23,7 @@
 #include <gtest/gtest.h>
 
 #include <asiolink/io_address.h>
+#include <util/networking.h>
 #include <dhcp/pkt6.h>
 #include <dhcp/iface_mgr.h>
 #include <dhcp/dhcp4.h>
@@ -30,6 +31,7 @@
 using namespace std;
 using namespace asio::detail;
 using namespace isc;
+using namespace isc::util;
 using namespace isc::asiolink;
 using namespace isc::dhcp;
 
@@ -242,8 +244,8 @@ TEST_F(IfaceMgrTest, sockets6) {
     // removed code for binding socket twice to the same address/port
     // as it caused problems on some platforms (e.g. Mac OS X)
 
-    close(socket1);
-    close(socket2);
+    closesocket(socket1);
+    closesocket(socket2);
 
     delete ifacemgr;
 }
@@ -258,7 +260,7 @@ TEST_F(IfaceMgrTest, socketsFromIface) {
     );
     // Socket descriptor must be positive integer
     EXPECT_NE(socket1, invalid_socket);
-    close(socket1);
+    closesocket(socket1);
 
     // Open v4 socket on loopback interface and bind to different port
     socket_type socket2 = invalid_socket;
@@ -267,7 +269,7 @@ TEST_F(IfaceMgrTest, socketsFromIface) {
     );
     // socket descriptor must be positive integer
     EXPECT_NE(socket2, invalid_socket);
-    close(socket2);
+    closesocket(socket2);
 
 }
 
@@ -283,7 +285,7 @@ TEST_F(IfaceMgrTest, socketsFromAddress) {
     );
     // socket descriptor must be positive integer
     EXPECT_NE(socket1, invalid_socket);
-    close(socket1);
+    closesocket(socket1);
 
     // Open v4 socket on loopback interface and bind to different port
     socket_type socket2 = invalid_socket;
@@ -293,7 +295,7 @@ TEST_F(IfaceMgrTest, socketsFromAddress) {
     );
     // socket descriptor must be positive integer
     EXPECT_NE(socket2, invalid_socket);
-    close(socket2);
+    closesocket(socket2);
 }
 
 TEST_F(IfaceMgrTest, socketsFromRemoteAddress) {
@@ -308,7 +310,7 @@ TEST_F(IfaceMgrTest, socketsFromRemoteAddress) {
         socket1 = ifacemgr->openSocketFromRemoteAddress(loAddr6, PORT1);
     );
     EXPECT_NE(socket1, invalid_socket);
-    close(socket1);
+    closesocket(socket1);
 
     // Open v4 socket to connect to remote address.
     socket_type socket2 = invalid_socket;
@@ -317,7 +319,7 @@ TEST_F(IfaceMgrTest, socketsFromRemoteAddress) {
         socket2 = ifacemgr->openSocketFromRemoteAddress(loAddr, PORT2);
     );
     EXPECT_NE(socket2, invalid_socket);
-    close(socket2);
+    closesocket(socket2);
 }
 
 // TODO: disabled due to other naming on various systems
@@ -345,8 +347,8 @@ TEST_F(IfaceMgrTest, DISABLED_sockets6Mcast) {
     // to iterate thru available interfaces and check if there
     // are interfaces without multicast-capable flag.
 
-    close(socket1);
-    close(socket2);
+    closesocket(socket1);
+    closesocket(socket2);
 
     delete ifacemgr;
 }
@@ -521,7 +523,7 @@ TEST_F(IfaceMgrTest, socket4) {
     // Expect that we get the socket that we just opened.
     EXPECT_EQ(socket1, ifacemgr->getSocket(pkt));
 
-    close(socket1);
+    closesocket(socket1);
 
     delete ifacemgr;
 }
diff --git a/src/lib/dns/masterload.cc b/src/lib/dns/masterload.cc
index 3deae19..48b4091 100644
--- a/src/lib/dns/masterload.cc
+++ b/src/lib/dns/masterload.cc
@@ -17,12 +17,13 @@
 #include <sstream>
 #include <string>
 #include <cctype>
-#include <cerrno>
 
 #include <boost/scoped_ptr.hpp>
 
 #include <exceptions/exceptions.h>
 
+#include <util/error.h>
+
 #include <dns/masterload.h>
 #include <dns/name.h>
 #include <dns/rdata.h>
@@ -73,7 +74,7 @@ masterLoad(const char* const filename, const Name& origin,
     ifs.open(filename, ios_base::in);
     if (ifs.fail()) {
         isc_throw(MasterLoadError, "Failed to open master file: " <<
-                  filename << ": " << strerror(errno));
+                  filename << ": " << isc::util::strerror());
     }
     masterLoad(ifs, origin, zone_class, callback);
     ifs.close();
diff --git a/src/lib/dns/rdata/in_1/a_1.cc b/src/lib/dns/rdata/in_1/a_1.cc
index 3b15a4c..8089c88 100644
--- a/src/lib/dns/rdata/in_1/a_1.cc
+++ b/src/lib/dns/rdata/in_1/a_1.cc
@@ -23,6 +23,7 @@
 #include <exceptions/exceptions.h>
 
 #include <util/buffer.h>
+#include <util/networking.h>
 #include <dns/exceptions.h>
 #include <dns/messagerenderer.h>
 #include <dns/rdata.h>
@@ -78,7 +79,10 @@ string
 A::toText() const {
     char addr_string[sizeof("255.255.255.255")];
 
-    if (inet_ntop(AF_INET, &addr_, addr_string, sizeof(addr_string)) == NULL) {
+    if (isc::util::inetntop(AF_INET,
+                            &addr_,
+                            addr_string,
+                            sizeof(addr_string)) == NULL) {
         isc_throw(Unexpected,
                   "Failed to convert IN/A RDATA to textual IPv4 address");
     }
diff --git a/src/lib/dns/rdata/in_1/aaaa_28.cc b/src/lib/dns/rdata/in_1/aaaa_28.cc
index ce49a04..93898af 100644
--- a/src/lib/dns/rdata/in_1/aaaa_28.cc
+++ b/src/lib/dns/rdata/in_1/aaaa_28.cc
@@ -75,7 +75,10 @@ string
 AAAA::toText() const {
     char addr_string[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
 
-    if (inet_ntop(AF_INET6, &addr_, addr_string, sizeof(addr_string)) == NULL) {
+    if (isc::util::inetntop(AF_INET6,
+                            &addr_,
+                            addr_string,
+                            sizeof(addr_string)) == NULL) {
         isc_throw(Unexpected,
                   "Failed to convert IN/AAAA RDATA to textual IPv6 address");
     }
diff --git a/src/lib/log/compiler/message.cc b/src/lib/log/compiler/message.cc
index 86c5f20..421849c 100644
--- a/src/lib/log/compiler/message.cc
+++ b/src/lib/log/compiler/message.cc
@@ -19,7 +19,6 @@
 #include <string>
 #include <vector>
 
-#include <errno.h>
 #include <getopt.h>
 #include <string.h>
 #include <time.h>
@@ -27,6 +26,7 @@
 
 #include <exceptions/exceptions.h>
 
+#include <util/error.h>
 #include <util/filename.h>
 #include <util/strutil.h>
 
@@ -329,7 +329,7 @@ writeHeaderFile(const string& file, const vector<string>& ns_components,
     if (hfile.fail()) {
         isc_throw_4(MessageException, "Failed to open output file",
                     LOG_OPEN_OUTPUT_FAIL, header_file.fullName(),
-                    strerror(errno), 0);
+                    strerror(), 0);
     }
 
     // Write the header preamble.  If there is an error, we'll pick it up
@@ -363,8 +363,7 @@ writeHeaderFile(const string& file, const vector<string>& ns_components,
     // Report errors (if any) and exit
     if (hfile.fail()) {
         isc_throw_4(MessageException, "Error writing to output file",
-                    LOG_WRITE_ERROR, header_file.fullName(), strerror(errno),
-                    0);
+                    LOG_WRITE_ERROR, header_file.fullName(), strerror(), 0);
     }
 
     hfile.close();
@@ -431,7 +430,7 @@ writeProgramFile(const string& file, const vector<string>& ns_components,
     if (ccfile.fail()) {
         isc_throw_4(MessageException, "Error opening output file",
                     LOG_OPEN_OUTPUT_FAIL, program_file.fullName(),
-                    strerror(errno), 0);
+                    strerror(), 0);
     }
 
     // Write the preamble.  If there is an error, we'll pick it up after
@@ -489,8 +488,7 @@ writeProgramFile(const string& file, const vector<string>& ns_components,
     // Report errors (if any) and exit
     if (ccfile.fail()) {
         isc_throw_4(MessageException, "Error writing to output file",
-                    LOG_WRITE_ERROR, program_file.fullName(), strerror(errno),
-                    0);
+                    LOG_WRITE_ERROR, program_file.fullName(), strerror(), 0);
     }
 
     ccfile.close();
diff --git a/src/lib/log/message_reader.cc b/src/lib/log/message_reader.cc
index b5a4d35..7985c6a 100644
--- a/src/lib/log/message_reader.cc
+++ b/src/lib/log/message_reader.cc
@@ -13,8 +13,6 @@
 // PERFORMANCE OF THIS SOFTWARE.
 
 #include <cassert>
-#include <errno.h>
-#include <string.h>
 #include <iostream>
 
 #include <iostream>
@@ -23,6 +21,7 @@
 #include <log/log_messages.h>
 #include <log/message_exception.h>
 #include <log/message_reader.h>
+#include <util/error.h>
 #include <util/strutil.h>
 
 using namespace std;
@@ -49,7 +48,7 @@ MessageReader::readFile(const string& file, MessageReader::Mode mode) {
     ifstream infile(file.c_str());
     if (infile.fail()) {
         isc_throw_4(MessageException, "Failed to open message file",
-                    LOG_INPUT_OPEN_FAIL, file, strerror(errno), 0);
+                    LOG_INPUT_OPEN_FAIL, file, isc::util::strerror(), 0);
     }
 
     // Loop round reading it.  As we process the file one line at a time,
@@ -67,7 +66,7 @@ MessageReader::readFile(const string& file, MessageReader::Mode mode) {
     // Why did the loop terminate?
     if (!infile.eof()) {
         isc_throw_4(MessageException, "Error reading message file",
-                    LOG_READ_ERROR, file, strerror(errno), 0);
+                    LOG_READ_ERROR, file, isc::util::strerror(), 0);
     }
     infile.close();
 }
diff --git a/src/lib/python/isc/util/cio/socketsessionreceiver_python.cc b/src/lib/python/isc/util/cio/socketsessionreceiver_python.cc
index 99629ba..a0ebc7b 100644
--- a/src/lib/python/isc/util/cio/socketsessionreceiver_python.cc
+++ b/src/lib/python/isc/util/cio/socketsessionreceiver_python.cc
@@ -34,12 +34,14 @@
 
 #include <util/python/pycppwrapper_util.h>
 
+#include <util/networking.h>
 #include <util/io/socketsession.h>
 
 #include "socketsession_python.h"
 #include "socketsessionreceiver_python.h"
 
 using namespace std;
+using namespace isc::util;
 using namespace isc::util::python;
 using namespace isc::util::io;
 using namespace isc::util::io::python;
@@ -162,7 +164,7 @@ SocketSessionReceiver_destroy(PyObject* po_self) {
 struct ScopedSocket : boost::noncopyable {
     ScopedSocket(socket_type sd) : sd_(sd) {}
     ~ScopedSocket() {
-        close(sd_);
+        closesocket(sd_);
     }
     const socket_type sd_;
 };
diff --git a/src/lib/resolve/tests/recursive_query_unittest.cc b/src/lib/resolve/tests/recursive_query_unittest.cc
index 5120f8a..82c5ff7 100644
--- a/src/lib/resolve/tests/recursive_query_unittest.cc
+++ b/src/lib/resolve/tests/recursive_query_unittest.cc
@@ -34,6 +34,7 @@
 #include <dns/rcode.h>
 
 #include <util/buffer.h>
+#include <util/networking.h>
 #include <util/unittests/resolver.h>
 #include <dns/message.h>
 #include <dns/rdataclass.h>
@@ -138,12 +139,12 @@ struct ScopedSocket : private boost::noncopyable {
     ScopedSocket(socket_type s) : s_(s) {}
     ~ScopedSocket() {
         if (s_ != invalid_socket) {
-            close(s_);
+            closesocket(s_);
         }
     }
     void reset(socket_type new_s) {
         if (s_ != invalid_socket) {
-            close(s_);
+            closesocket(s_);
         }
         s_ = new_s;
     }
@@ -232,7 +233,7 @@ protected:
         }
 
         if (bind(sock_.s_, res->ai_addr, res->ai_addrlen) < 0) {
-            isc_throw(IOError, "bind failed: " << strerror(errno));
+            isc_throw(IOError, "bind failed: " << strneterror());
         }
 
         // The IO service queue should have a RecursiveQuery object scheduled
@@ -251,9 +252,9 @@ protected:
         // we add an ad hoc timeout.
         const struct timeval timeo = { 10, 0 };
         int recv_options = 0;
-        if (setsockopt(sock_.s_, SOL_SOCKET, SO_RCVTIMEO, &timeo,
-                       sizeof(timeo))) {
-            if (errno == ENOPROTOOPT) {
+        if (setsockopt(sock_.s_, SOL_SOCKET, SO_RCVTIMEO,
+                       (char *)&timeo, sizeof(timeo))) {
+            if (getneterror() == ENOPROTOOPT) {
                 // Workaround for Solaris: it doesn't accept SO_RCVTIMEO
                 // with the error of ENOPROTOOPT.  Since this is a workaround
                 // for rare error cases anyway, we simply switch to the
@@ -261,12 +262,12 @@ protected:
                 // can happen often we'll consider a more complete solution.
                 recv_options = MSG_DONTWAIT;
             } else {
-                isc_throw(IOError, "set RCVTIMEO failed: " << strerror(errno));
+                isc_throw(IOError, "set RCVTIMEO failed: " << strneterror());
             }
         }
         const int ret = recv(sock_.s_, buffer, size, recv_options);
         if (ret < 0) {
-            isc_throw(IOError, "recvfrom failed: " << strerror(errno));
+            isc_throw(IOError, "recvfrom failed: " << strneterror());
         }
         
         // Pass the message size back via the size parameter
@@ -287,13 +288,14 @@ protected:
         }
         const int on = 1;
         if (family == AF_INET6) {
-            if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) ==
-                -1) {
+            if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
+                           (char *)&on, sizeof(on)) == socket_error_retval) {
                 isc_throw(isc::Unexpected,
                           "failed to set socket option(IPV6_V6ONLY)");
             }
         }
-        if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) {
+        if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
+                       (char *)&on, sizeof(on)) == socket_error_retval) {
             isc_throw(isc::Unexpected,
                       "failed to set socket option(SO_REUSEADDR)");
         }
@@ -699,11 +701,12 @@ int
 setSocketTimeout(int sock, size_t tv_sec, size_t tv_usec) {
     const struct timeval timeo = { tv_sec, tv_usec };
     int recv_options = 0;
-    if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo))) {
-        if (errno == ENOPROTOOPT) { // see RecursiveQueryTest::recvUDP()
+    if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,
+                   (char *)&timeo, sizeof(timeo))) {
+        if (getneterror() == ENOPROTOOPT) { // see RecursiveQueryTest::recvUDP()
             recv_options = MSG_DONTWAIT;
         } else {
-            isc_throw(IOError, "set RCVTIMEO failed: " << strerror(errno));
+            isc_throw(IOError, "set RCVTIMEO failed: " << strneterror());
         }
     }
     return (recv_options);
diff --git a/src/lib/server_common/socket_request.cc b/src/lib/server_common/socket_request.cc
index 4f7565d..2829b01 100644
--- a/src/lib/server_common/socket_request.cc
+++ b/src/lib/server_common/socket_request.cc
@@ -19,12 +19,13 @@
 #include <config/ccsession.h>
 #include <cc/session.h>
 #include <cc/data.h>
+#include <util/error.h>
+#include <util/networking.h>
 #include <util/io/socket.h>
 #include <util/io/socket_share.h>
 
 #include <sys/un.h>
 #include <sys/socket.h>
-#include <cerrno>
 #include <csignal>
 #include <cstddef>
 
@@ -179,12 +180,12 @@ createSdShareSocket(const std::string& path) {
     if (sock_pass_sd == invalid_socket) {
         isc_throw(SocketRequestor::SocketError,
                   "Unable to open domain socket " << path <<
-                  ": " << strerror(errno));
+                  ": " << isc::util::strneterror());
     }
     struct sockaddr_un sock_pass_addr;
     sock_pass_addr.sun_family = AF_UNIX;
     if (path.size() >= sizeof(sock_pass_addr.sun_path)) {
-        close(sock_pass_sd);
+        isc::util::closesocket(sock_pass_sd);
         isc_throw(SocketRequestor::SocketError,
                   "Unable to open domain socket " << path <<
                   ": path too long");
@@ -197,10 +198,10 @@ createSdShareSocket(const std::string& path) {
     // Yes, C-style cast bad. See previous comment about SocketSessionReceiver.
     if (connect(sock_pass_sd, (const struct sockaddr*)&sock_pass_addr,
                 len) == -1) {
-        close(sock_pass_sd);
+        isc::util::closesocket(sock_pass_sd);
         isc_throw(SocketRequestor::SocketError,
                   "Unable to open domain socket " << path <<
-                  ": " << strerror(errno));
+                  ": " << isc::util::strneterror());
     }
     return (sock_pass_sd);
 }
@@ -271,6 +272,7 @@ public:
         session_(session),
         app_name_(app_name)
     {
+#ifndef _WIN32
         // We need to filter SIGPIPE to prevent it from happening in
         // getSocketSd() while writing to the UNIX domain socket after the
         // remote end closed it.  See lib/util/io/socketsession for more
@@ -280,8 +282,9 @@ public:
         // term workaround.
         if (std::signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
             isc_throw(Unexpected, "Failed to filter SIGPIPE: " <<
-                      strerror(errno));
+                      isc::util::strerror());
         }
+#endif
         LOG_DEBUG(logger, DBGLVL_TRACE_BASIC, SOCKETREQUESTOR_CREATED).
             arg(app_name);
     }
@@ -376,11 +379,11 @@ private:
     // Closes the sockets that has been used for socket_share
     void
     closeSdShareSockets() {
-        for (std::map<std::string, int>::const_iterator it =
+        for (std::map<std::string, socket_type>::const_iterator it =
                 share_sockets_.begin();
              it != share_sockets_.end();
              ++it) {
-            close((*it).second);
+            isc::util::closesocket((*it).second);
         }
     }
 
diff --git a/src/lib/server_common/tests/socket_requestor_test.cc b/src/lib/server_common/tests/socket_requestor_test.cc
index daaec92..86ac1f4 100644
--- a/src/lib/server_common/tests/socket_requestor_test.cc
+++ b/src/lib/server_common/tests/socket_requestor_test.cc
@@ -26,16 +26,18 @@
 
 #include <cstdlib>
 #include <cstddef>
-#include <cerrno>
 #include <sys/socket.h>
 #include <sys/un.h>
 
 #include <boost/foreach.hpp>
 #include <boost/scoped_ptr.hpp>
 
+#include <util/error.h>
+#include <util/networking.h>
 #include <util/io/socket.h>
 #include <util/io/socket_share.h>
 
+using namespace isc::util;
 using namespace isc::data;
 using namespace isc::config;
 using namespace isc::server_common;
@@ -327,13 +329,14 @@ TEST_F(SocketRequestorTest, testBadSocketReleaseAnswers) {
 bool
 setRecvTimo(socket_type s) {
     const struct timeval timeo = { 10, 0 }; // 10sec, arbitrary choice
-    if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo)) == 0) {
+    if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO,
+                   (char *)&timeo, sizeof(timeo)) == 0) {
         return (true);
     }
-    if (errno == ENOPROTOOPT) { // deviant OS, give up using it.
+    if (getneterror() == ENOPROTOOPT) { // deviant OS, give up using it.
         return (false);
     }
-    isc_throw(isc::Unexpected, "set RCVTIMEO failed: " << strerror(errno));
+    isc_throw(isc::Unexpected, "set RCVTIMEO failed: " << strneterror());
 }
 
 // Helper test class that creates a randomly named domain socket
@@ -349,10 +352,10 @@ public:
         // Misuse mkstemp to generate a file name.
         const int f = mkstemp(path_);
         if (f == -1) {
-            isc_throw(Unexpected, "mkstemp failed: " << strerror(errno));
+            isc_throw(Unexpected, "mkstemp failed: " << strerror());
         }
         // Just need the name, so immediately close
-        close(f);
+        closesocket(f);
     }
 
     ~TestSocket() {
@@ -367,7 +370,7 @@ public:
             path_ = NULL;
         }
         if (sd_ != invalid_socket) {
-            close(sd_);
+            closesocket(sd_);
             sd_ = invalid_socket;
         }
     }
@@ -390,7 +393,7 @@ public:
             exit(0);
         } else {
             // parent does not need sd_ anymore
-            close(sd_);
+            closesocket(sd_);
             sd_ = invalid_socket;
         }
         return (timo_ok);
@@ -423,13 +426,13 @@ private:
         if (bind(sd_, (const struct sockaddr*)&socket_address, len) == -1) {
             isc_throw(Unexpected,
                       "unable to bind to test domain socket " << path_ <<
-                      ": " << strerror(errno));
+                      ": " << strneterror());
         }
 
         if (listen(sd_, 1) == -1) {
             isc_throw(Unexpected,
                       "unable to listen on test domain socket " << path_ <<
-                      ": " << strerror(errno));
+                      ": " << strneterror());
         }
     }
 
@@ -453,7 +456,7 @@ private:
     serve(const std::vector<std::pair<std::string, int> >& data) {
         const socket_type client_sd = accept(sd_, NULL, NULL);
         if (client_sd == invalid_socket) {
-            isc_throw(Unexpected, "Error in accept(): " << strerror(errno));
+            isc_throw(Unexpected, "Error in accept(): " << strneterror());
         }
         if (!setRecvTimo(client_sd)) {
             // In the loop below we do blocking read.  To avoid deadlock
@@ -496,11 +499,11 @@ private:
                 }
             }
             if (!result) {
-                isc_throw(Exception, "Error in send_socket(): " <<
-                          strerror(errno));
+                isc_throw(Exception,
+                          "Error in send_socket(): " << strerror());
             }
         }
-        close(client_sd);
+        closesocket(client_sd);
     }
 
     socket_type sd_;
@@ -528,19 +531,19 @@ TEST_F(SocketRequestorTest, testSocketPassing) {
         addAnswer("foo", ts.getPath());
         socket_id = doRequest();
         EXPECT_EQ("foo", socket_id.second);
-        EXPECT_EQ(0, close(socket_id.first));
+        EXPECT_EQ(0, closesocket(socket_id.first));
 
         // 2 should be ok too
         addAnswer("bar", ts.getPath());
         socket_id = doRequest();
         EXPECT_EQ("bar", socket_id.second);
-        EXPECT_EQ(0, close(socket_id.first));
+        EXPECT_EQ(0, closesocket(socket_id.first));
 
         // 3 should be ok too (reuse earlier token)
         addAnswer("foo", ts.getPath());
         socket_id = doRequest();
         EXPECT_EQ("foo", socket_id.second);
-        EXPECT_EQ(0, close(socket_id.first));
+        EXPECT_EQ(0, closesocket(socket_id.first));
     }
 
     // Create a second socket server, to test that multiple different
@@ -556,7 +559,7 @@ TEST_F(SocketRequestorTest, testSocketPassing) {
         addAnswer("foo", ts2.getPath());
         socket_id = doRequest();
         EXPECT_EQ("foo", socket_id.second);
-        EXPECT_EQ(0, close(socket_id.first));
+        EXPECT_EQ(0, closesocket(socket_id.first));
     }
 
     if (timo_ok) {
@@ -564,7 +567,7 @@ TEST_F(SocketRequestorTest, testSocketPassing) {
         addAnswer("foo", ts.getPath());
         socket_id = doRequest();
         EXPECT_EQ("foo", socket_id.second);
-        EXPECT_EQ(0, close(socket_id.first));
+        EXPECT_EQ(0, closesocket(socket_id.first));
 
         // -1 is a "normal" error
         addAnswer("foo", ts.getPath());
diff --git a/src/lib/util/error.h b/src/lib/util/error.h
new file mode 100644
index 0000000..300deb1
--- /dev/null
+++ b/src/lib/util/error.h
@@ -0,0 +1,56 @@
+// Copyright (C) 2012  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef __ERROR_H
+#define __ERROR_H
+
+#include <cstring>
+#include <cerrno>
+
+namespace isc {
+namespace util {
+
+/// \brief Error code portability inlines
+
+inline int geterror(void) {
+#ifdef _WIN32
+    return (GetLastError());
+#else
+    return (errno);
+#endif
+}
+
+inline void seterror(int errnum) {
+#ifdef _WIN32
+    SetLastError(errnum);
+#else
+    errno = errnum;
+#endif
+}
+
+inline char *strerror(void) {
+#ifdef _WIN32
+#define ERRBUF 128
+    static char buf[ERRBUF];
+    strerror_s<ERRBUF>(buf, geterror());
+    return (buf);
+#else
+    return (::strerror(geterror()));
+#endif
+}
+
+} // namespace util
+} // namespace isc
+
+#endif // __ERROR_H
diff --git a/src/lib/util/io/socket.cc b/src/lib/util/io/socket.cc
index 77d5141..932cb30 100644
--- a/src/lib/util/io/socket.cc
+++ b/src/lib/util/io/socket.cc
@@ -14,8 +14,10 @@
 
 #include "socket.h"
 
+#include <util/error.h>
+#include <util/networking.h>
+
 #include <unistd.h>
-#include <cerrno>
 
 namespace isc {
 namespace util {
@@ -30,7 +32,7 @@ write_data(const socket_type s, const void *buffer_v, const size_t length) {
     while (remaining > 0) {
         const int written = write(s, buffer, remaining);
         if (written == -1) {
-            if (errno == EINTR) { // Just keep going
+            if (isc::util::geterror() == EINTR) { // Just keep going
                 continue;
             } else {
                 return (false);
@@ -60,7 +62,8 @@ read_data(const socket_type s, void *buffer_v, const size_t length) {
     while (remaining > 0) {
         const int amount = read(s, buffer, remaining);
         if (amount == -1) {
-            if (errno == EINTR) { // Continue on interrupted call
+            if (isc::util::geterror() == EINTR) {
+                // Continue on interrupted call
                 continue;
             } else {
                 return (-1);
diff --git a/src/lib/util/io/socket_share.cc b/src/lib/util/io/socket_share.cc
index fccea6e..70e21b9 100644
--- a/src/lib/util/io/socket_share.cc
+++ b/src/lib/util/io/socket_share.cc
@@ -18,10 +18,13 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/uio.h>
-#include <errno.h>
 #include <stdlib.h>             // for malloc and free
 #include <unistd.h>
 #include "socket_share.h"
+#include <util/error.h>
+#include <util/networking.h>
+
+using isc::util::closesocket;
 
 namespace isc {
 namespace util {
@@ -97,7 +100,7 @@ recv_socket(const socket_type sock, socket_type *val) {
     if (cc <= 0) {
         free(msghdr.msg_control);
         if (cc == 0) {
-            errno = ECONNRESET;
+            setneterror(ECONNRESET);
         }
         return (SOCKET_SYSTEM_ERROR);
     }
@@ -112,13 +115,14 @@ recv_socket(const socket_type sock, socket_type *val) {
     // one returned previously, even if that one is not closed yet. So,
     // we just re-number every one we get, so they are unique.
     socket_type new_sd(dup(s));
-    int close_error(close(s));
+    int close_error(closesocket(s));
     if (close_error == socket_error_retval || new_sd == invalid_socket) {
         // We need to return an error, because something failed. But in case
         // it was the previous close, we at least try to close the duped SD.
         if (new_sd != invalid_socket) {
-            close(new_sd); // If this fails, nothing but returning error can't
-                           // be done and we are doing that anyway.
+            closesocket(new_sd); // If this fails, nothing but returning error
+                                 // can't be done and we are doing that anyway.
+
         }
         return (SOCKET_SYSTEM_ERROR);
     }
diff --git a/src/lib/util/io/socketsession.cc b/src/lib/util/io/socketsession.cc
index ddcb90d..8a5de95 100644
--- a/src/lib/util/io/socketsession.cc
+++ b/src/lib/util/io/socketsession.cc
@@ -24,7 +24,6 @@
 #include <fcntl.h>
 #include <stdint.h>
 
-#include <cerrno>
 #include <csignal>
 #include <cstddef>
 #include <cstring>
@@ -38,12 +37,15 @@
 #include <exceptions/exceptions.h>
 
 #include <util/buffer.h>
+#include <util/error.h>
+#include <util/networking.h>
 
 #include "socket_share.h"
 #include "socketsession.h"
 #include "sockaddr_util.h"
 
 using namespace std;
+using namespace isc::util;
 
 namespace isc {
 namespace util {
@@ -95,7 +97,7 @@ SocketSessionForwarder::SocketSessionForwarder(const std::string& unix_file) :
     // We need to filter SIGPIPE for subsequent push().  See the class
     // description.
     if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
-        isc_throw(Unexpected, "Failed to filter SIGPIPE: " << strerror(errno));
+        isc_throw(Unexpected, "Failed to filter SIGPIPE: " << strneterror());
     }
 
     ForwarderImpl impl;
@@ -139,7 +141,7 @@ SocketSessionForwarder::connectToReceiver() {
     impl_->sd_ = socket(AF_UNIX, SOCK_STREAM, 0);
     if (impl_->sd_ == invalid_socket) {
         isc_throw(SocketSessionError, "Failed to create a UNIX domain socket: "
-                  << strerror(errno));
+                  << strneterror());
     }
     // Make the socket non blocking
     int fcntl_flags = fcntl(impl_->sd_, F_GETFL, 0);
@@ -151,17 +153,23 @@ SocketSessionForwarder::connectToReceiver() {
         close();   // note: this is the internal method, not ::close()
         isc_throw(SocketSessionError,
                   "Failed to make UNIX domain socket non blocking: " <<
-                  strerror(errno));
+                  strerror());
     }
     // Ensure the socket send buffer is large enough.  If we can't get the
     // current size, simply set the sufficient size.
     int sndbuf_size;
     socklen_t sndbuf_size_len = sizeof(sndbuf_size);
-    if (getsockopt(impl_->sd_, SOL_SOCKET, SO_SNDBUF, &sndbuf_size,
-                   &sndbuf_size_len) == -1 ||
+    if (getsockopt(impl_->sd_,
+                   SOL_SOCKET,
+                   SO_SNDBUF,
+                   (char *) &sndbuf_size,
+                   &sndbuf_size_len) == socket_error_retval ||
         sndbuf_size < SOCKSESSION_BUFSIZE) {
-        if (setsockopt(impl_->sd_, SOL_SOCKET, SO_SNDBUF, &SOCKSESSION_BUFSIZE,
-                       sizeof(SOCKSESSION_BUFSIZE)) == -1) {
+        if (setsockopt(impl_->sd_,
+                       SOL_SOCKET,
+                       SO_SNDBUF,
+                       (char *) &SOCKSESSION_BUFSIZE,
+                       sizeof(SOCKSESSION_BUFSIZE)) == socket_error_retval) {
             close();
             isc_throw(SocketSessionError, "Failed to set send buffer size");
         }
@@ -171,7 +179,7 @@ SocketSessionForwarder::connectToReceiver() {
         close();
         isc_throw(SocketSessionError, "Failed to connect to UNIX domain "
                   "endpoint " << impl_->sock_un_.sun_path << ": " <<
-                  strerror(errno));
+                  strneterror());
     }
 }
 
@@ -180,7 +188,7 @@ SocketSessionForwarder::close() {
     if (impl_->sd_ == invalid_socket) {
         isc_throw(BadValue, "Attempt of close before connect");
     }
-    ::close(impl_->sd_);
+    closesocket(impl_->sd_);
     impl_->sd_ = invalid_socket;
 }
 
@@ -218,7 +226,7 @@ SocketSessionForwarder::push(socket_type sock,
 
     if (send_socket(impl_->sd_, sock) != 0) {
         isc_throw(SocketSessionError, "socket passing failed: " <<
-                  strerror(errno));
+                  strneterror());
     }
 
     impl_->buf_.clear();
@@ -250,7 +258,7 @@ SocketSessionForwarder::push(socket_type sock,
         if (cc < 0) {
             isc_throw(SocketSessionError,
                       "Write failed in forwarding a socket session: " <<
-                      strerror(errno));
+                      strerror());
         }
         isc_throw(SocketSessionError,
                   "Incomplete write in forwarding a socket session: " << cc <<
@@ -285,8 +293,11 @@ struct SocketSessionReceiver::ReceiverImpl {
                                    header_buf_(DEFAULT_HEADER_BUFLEN),
                                    data_buf_(INITIAL_BUFSIZE)
     {
-        if (setsockopt(sd_, SOL_SOCKET, SO_RCVBUF, &SOCKSESSION_BUFSIZE,
-                       sizeof(SOCKSESSION_BUFSIZE)) == -1) {
+        if (setsockopt(sd_,
+                       SOL_SOCKET,
+                       SO_RCVBUF,
+                       (char *) &SOCKSESSION_BUFSIZE,
+                       sizeof(SOCKSESSION_BUFSIZE)) == socket_error_retval) {
             isc_throw(SocketSessionError,
                       "Failed to set receive buffer size");
         }
@@ -318,7 +329,7 @@ void
 readFail(int actual_len, int expected_len) {
     if (expected_len < 0) {
         isc_throw(SocketSessionError, "Failed to receive data from "
-                  "SocketSessionForwarder: " << strerror(errno));
+                  "SocketSessionForwarder: " << strneterror());
     }
     isc_throw(SocketSessionError, "Incomplete data from "
               "SocketSessionForwarder: " << actual_len << "/" <<
@@ -332,7 +343,7 @@ struct ScopedSocket : boost::noncopyable {
     ScopedSocket(socket_type sd) : sd_(sd) {}
     ~ScopedSocket() {
         if (sd_ != invalid_socket) {
-            close(sd_);
+            closesocket(sd_);
         }
     }
     int release() {
@@ -349,7 +360,7 @@ SocketSessionReceiver::pop() {
     ScopedSocket passed_sock(invalid_socket);
     if (recv_socket(impl_->sd_, &passed_sock.sd_) == SOCKET_SYSTEM_ERROR) {
         isc_throw(SocketSessionError,
-                  "Receiving a forwarded socket failed: " << strerror(errno));
+                  "Receiving a forwarded socket failed: " << strneterror());
     } else if (passed_sock.sd_ == invalid_socket) {
         isc_throw(SocketSessionError, "No socket forwarded");
     }
diff --git a/src/lib/util/networking.h b/src/lib/util/networking.h
new file mode 100644
index 0000000..f16012d
--- /dev/null
+++ b/src/lib/util/networking.h
@@ -0,0 +1,73 @@
+// Copyright (C) 2012  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef __NETWORKING_H
+#define __NETWORKING_H
+
+#include <cstring>
+#include <cerrno>
+#include <asio/detail/socket_types.hpp>
+
+namespace isc {
+namespace util {
+
+/// \brief Networking code portability inlines
+
+inline int closesocket(asio::detail::socket_type sd) {
+#ifdef _WIN32
+    return (::closesocket(sd));
+#else
+    return (close(sd));
+#endif
+}
+
+inline int getneterror(void) {
+#ifdef _WIN32
+    return (WSAGetLastError());
+#else
+    return (errno);
+#endif
+}
+
+inline void setneterror(int errnum) {
+#ifdef _WIN32
+    WSASetLastError(errnum);
+#else
+    errno = errnum;
+#endif
+}
+
+inline char *strneterror(void) {
+#ifdef _WIN32
+#define ERRBUF 128
+    static char buf[ERRBUF];
+    strerror_s<ERRBUF>(buf, getneterror());
+    return (buf);
+#else
+    return (::strerror(getneterror()));
+#endif
+}
+
+inline const char *inetntop(int af, const void *src, char *dst, size_t size) {
+#ifdef _WIN32
+    return (inet_ntop(af, (void *)src, dst, size));
+#else
+    return (inet_ntop(af, src, dst, size));
+#endif
+}
+
+} // namespace util
+} // namespace isc
+
+#endif // __NETWORKING_H
diff --git a/src/lib/util/tests/socket_share_tests.cc b/src/lib/util/tests/socket_share_tests.cc
index 2652afe..7a09d16 100644
--- a/src/lib/util/tests/socket_share_tests.cc
+++ b/src/lib/util/tests/socket_share_tests.cc
@@ -14,6 +14,7 @@
 
 #include <util/io/socket.h>
 #include <util/io/socket_share.h>
+#include <util/networking.h>
 
 #include <util/unittests/fork.h>
 
@@ -23,6 +24,7 @@
 #include <sys/socket.h>
 #include <cstdio>
 
+using namespace isc::util;
 using namespace isc::util::io;
 using namespace isc::util::unittests;
 
@@ -45,7 +47,7 @@ TEST(SDShare, transfer) {
         // Now, send the socket descriptor, close it and close the pipe
         EXPECT_NE(-1, send_socket(pipes[1], sd));
         EXPECT_NE(-1, close(pipes[1]));
-        EXPECT_NE(-1, close(sd));
+        EXPECT_NE(socket_error_retval, closesocket(sd));
         // Check both subprocesses ended well
         EXPECT_TRUE(process_ok(sender));
         EXPECT_TRUE(process_ok(checker));
@@ -64,7 +66,8 @@ TEST(SDShare, transfer) {
             exit(1);
         }
         // Send "data" trough the received socket, close it and be done
-        if(!write_data(sd, "data", 4) || close(sd) == -1) {
+        if(!write_data(sd, "data", 4) ||
+           closesocket(sd) == socket_error_retval) {
             exit(1);
         }
         exit(0);
diff --git a/src/lib/util/tests/socketsession_unittest.cc b/src/lib/util/tests/socketsession_unittest.cc
index fb33762..b4943f1 100644
--- a/src/lib/util/tests/socketsession_unittest.cc
+++ b/src/lib/util/tests/socketsession_unittest.cc
@@ -23,9 +23,6 @@
 #include <netdb.h>
 #include <unistd.h>
 
-#include <cerrno>
-#include <cstring>
-
 #include <algorithm>
 #include <string>
 #include <utility>
@@ -41,6 +38,8 @@
 #include <exceptions/exceptions.h>
 
 #include <util/buffer.h>
+#include <util/error.h>
+#include <util/networking.h>
 #include <util/io/socket_share.h>
 #include <util/io/socketsession.h>
 #include <util/io/sockaddr_util.h>
@@ -49,6 +48,7 @@ using namespace std;
 using namespace isc;
 using namespace asio::detail;
 using boost::scoped_ptr;
+using namespace isc::util;
 using namespace isc::util::io;
 using namespace isc::util::io::internal;
 
@@ -75,7 +75,7 @@ struct ScopedSocket : boost::noncopyable {
 private:
     void closeSocket() {
         if (sd != invalid_socket) {
-            close(sd);
+            closesocket(sd);
         }
     }
 };
@@ -92,7 +92,7 @@ setNonBlock(socket_type s, bool on) {
     }
     if (fcntl(s, F_SETFL, fcntl_flags) == -1) {
         isc_throw(isc::Unexpected, "fcntl(O_NONBLOCK) failed: " <<
-                  strerror(errno));
+                  strerror());
     }
 }
 
@@ -102,13 +102,17 @@ setNonBlock(socket_type s, bool on) {
 int
 setRecvDelay(socket_type s) {
     const struct timeval timeo = { 10, 0 };
-    if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo)) == -1) {
-        if (errno == ENOPROTOOPT) {
+        if (setsockopt(s,
+                       SOL_SOCKET,
+                       SO_RCVTIMEO,
+                       (char *) &timeo,
+                       sizeof(timeo)) == socket_error_retval) {
+        if (getneterror() == ENOPROTOOPT) {
             // Workaround for Solaris: see recursive_query_unittest
             return (MSG_DONTWAIT);
         } else {
             isc_throw(isc::Unexpected, "set RCVTIMEO failed: " <<
-                      strerror(errno));
+                      strneterror());
         }
     }
     return (0);
@@ -172,7 +176,7 @@ protected:
 
     ~ForwardTest() {
         if (listen_sd_ != invalid_socket) {
-            close(listen_sd_);
+            closesocket(listen_sd_);
         }
         unlink(TEST_UNIX_FILE);
     }
@@ -185,16 +189,16 @@ protected:
         listen_sd_ = socket(AF_UNIX, SOCK_STREAM, 0);
         if (listen_sd_ == invalid_socket) {
             isc_throw(isc::Unexpected, "failed to create UNIX domain socket" <<
-                      strerror(errno));
+                      strneterror());
         }
         if (bind(listen_sd_, convertSockAddr(&test_un_), test_un_len_) == -1) {
             isc_throw(isc::Unexpected, "failed to bind UNIX domain socket" <<
-                      strerror(errno));
+                      strneterror());
         }
         // 10 is an arbitrary choice, should be sufficient for a single test
         if (listen(listen_sd_, 10) == -1) {
             isc_throw(isc::Unexpected, "failed to listen on UNIX domain socket"
-                      << strerror(errno));
+                      << strneterror());
         }
     }
 
@@ -223,7 +227,7 @@ protected:
                                      convertSockAddr(&from),
                                      &from_len);
         if (s == invalid_socket) {
-            isc_throw(isc::Unexpected, "accept failed: " << strerror(errno));
+            isc_throw(isc::Unexpected, "accept failed: " << strneterror());
         }
         // Make sure the socket is *blocking*.  We may pass large data, through
         // it, and apparently non blocking read could cause some unexpected
@@ -247,23 +251,25 @@ protected:
     {
         socket_type s = socket(family, type, protocol);
         if (s == invalid_socket) {
-            isc_throw(isc::Unexpected, "socket(2) failed: " <<
-                      strerror(errno));
+            isc_throw(isc::Unexpected, "socket(2) failed: " << strneterror());
         }
         const int on = 1;
-        if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) {
+        if (setsockopt(s,
+                       SOL_SOCKET,
+                       SO_REUSEADDR,
+                       (char *) &on,
+                       sizeof(on)) == socket_error_retval) {
             isc_throw(isc::Unexpected, "setsockopt(SO_REUSEADDR) failed: " <<
-                      strerror(errno));
+                      strneterror());
         }
         if (bind(s, sainfo.first, sainfo.second) < 0) {
-            close(s);
-            isc_throw(isc::Unexpected, "bind(2) failed: " <<
-                      strerror(errno));
+            closesocket(s);
+            isc_throw(isc::Unexpected, "bind(2) failed: " << strneterror());
         }
         if (do_listen && protocol == IPPROTO_TCP) {
             if (listen(s, 1) == -1) {
                 isc_throw(isc::Unexpected, "listen(2) failed: " <<
-                          strerror(errno));
+                          strneterror());
             }
         }
         return (s);
@@ -476,7 +482,7 @@ ForwardTest::checkPushAndPop(int family, int type, int protocol,
         server_sock.reset(accept(sock.sd, convertSockAddr(&ss), &salen));
         if (server_sock.sd == invalid_socket) {
             isc_throw(isc::Unexpected, "internal accept failed: " <<
-                      strerror(errno));
+                      strneterror());
         }
         fwd_sd = server_sock.sd;
     }
@@ -670,7 +676,7 @@ TEST_F(ForwardTest, badPush) {
     // Close the receiver before push.  It will result in SIGPIPE (should be
     // ignored) and EPIPE, which will be converted to SocketSessionError.
     const int receiver_sd = acceptForwarder();
-    close(receiver_sd);
+    closesocket(receiver_sd);
     EXPECT_THROW(forwarder_.push(1, AF_INET, SOCK_DGRAM, IPPROTO_UDP,
                                  *getSockAddr("192.0.2.1", "53").first,
                                  *getSockAddr("192.0.2.2", "53").first,
diff --git a/src/lib/util/unittests/fork.cc b/src/lib/util/unittests/fork.cc
index c66587a..15d9f60 100644
--- a/src/lib/util/unittests/fork.cc
+++ b/src/lib/util/unittests/fork.cc
@@ -14,6 +14,7 @@
 
 #include "fork.h"
 
+#include <util/error.h>
 #include <util/io/socket.h>
 
 #include <sys/types.h>
@@ -21,7 +22,6 @@
 #include <unistd.h>
 #include <signal.h>
 #include <string.h>
-#include <cerrno>
 #include <stdlib.h>
 #include <stdio.h>
 



More information about the bind10-changes mailing list