From: Marcin Siodelski Date: Wed, 10 Sep 2014 08:04:33 +0000 (+0200) Subject: [3357] Refactored BaseIPC to UnixSocket. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=21549b839c93617cc5d99e99693c9a99721c650b;p=thirdparty%2Fkea.git [3357] Refactored BaseIPC to UnixSocket. --- diff --git a/src/lib/dhcpsrv/dhcp4o6_ipc.cc b/src/lib/dhcpsrv/dhcp4o6_ipc.cc index 42510cbadd..2ae767cd98 100644 --- a/src/lib/dhcpsrv/dhcp4o6_ipc.cc +++ b/src/lib/dhcpsrv/dhcp4o6_ipc.cc @@ -19,7 +19,7 @@ namespace isc { namespace dhcp { DHCP4o6IPC::DHCP4o6IPC(const std::string& local_filename, const std::string& remote_filename) : - BaseIPC(local_filename, remote_filename) { + UnixSocket(local_filename, remote_filename) { open(); } @@ -42,7 +42,7 @@ DHCP4o6IPC::sendPkt4o6(const Pkt4o6Ptr& pkt4o6) { buf.writeData(&len, sizeof(size_t)); buf.writeData(att.c_str(), len); - BaseIPC::send(buf); + UnixSocket::send(buf); } void diff --git a/src/lib/dhcpsrv/dhcp4o6_ipc.h b/src/lib/dhcpsrv/dhcp4o6_ipc.h index 3b0fe19a8c..97a926850f 100644 --- a/src/lib/dhcpsrv/dhcp4o6_ipc.h +++ b/src/lib/dhcpsrv/dhcp4o6_ipc.h @@ -16,7 +16,7 @@ #define DHCP4O6_IPC_H #include -#include +#include #include @@ -24,19 +24,19 @@ namespace isc { namespace dhcp { /// @brief Exception thrown when DHCP4o6IPC::send() failed. -class DHCP4o6IPCSendError : public isc::util::IPCSendError { +class DHCP4o6IPCSendError : public isc::util::UnixSocketSendError { public: DHCP4o6IPCSendError(const char* file, size_t line, const char* what) : - isc::util::IPCSendError(file, line, what) { }; + isc::util::UnixSocketSendError(file, line, what) { }; }; /// @brief IPC class to pass Pkt4o6 between DHCPv4 and DHCPv6 servers -class DHCP4o6IPC : public isc::util::BaseIPC { +class DHCP4o6IPC : public isc::util::UnixSocket { public: /// @brief Default constructor. /// - /// This function calls BaseIPC::open() to initiate socket directly - /// Method will throw if BaseIPC::open() method failed + /// This function calls UnixSocket::open() to initiate socket directly + /// Method will throw if UnixSocket::open() method failed /// /// @param local_filename Filename for receiving socket /// @param remote_filename Filename for sending socket @@ -45,18 +45,18 @@ public: /// @brief Send a DHCPv4 ove DHCPv6 packet /// /// This function converts Pkt4o6 into binary data and sends it - /// through BaseIPC::send(). - /// Method will throw if BaseIPC::send() failed + /// through UnixSocket::send(). + /// Method will throw if UnixSocket::send() failed /// /// @param pkt4o6 Pointer to the packet to be sent void sendPkt4o6(const Pkt4o6Ptr& pkt4o6); /// @brief Receive a DHCPv4 ove DHCPv6 packet /// - /// This function calls BaseIPC::recv() to receive binary data + /// This function calls UnixSocket::recv() to receive binary data /// and converts it into Pkt4o6 /// It pushes received Pkt4o6 into a queue and does not return immediately. - /// Method will throw if BaseIPC::recv() failed or Pkt4o6 + /// Method will throw if UnixSocket::recv() failed or Pkt4o6 /// construction failed void recvPkt4o6(); diff --git a/src/lib/util/Makefile.am b/src/lib/util/Makefile.am index aa6b5776c7..1809e73997 100644 --- a/src/lib/util/Makefile.am +++ b/src/lib/util/Makefile.am @@ -40,9 +40,7 @@ libkea_util_la_SOURCES += encode/binary_from_base32hex.h libkea_util_la_SOURCES += encode/binary_from_base16.h libkea_util_la_SOURCES += random/qid_gen.h random/qid_gen.cc libkea_util_la_SOURCES += random/random_number_generator.h - -#4o6 -libkea_util_la_SOURCES += ipc.h +libkea_util_la_SOURCES += unix_socket.cc unix_socket.h libkea_util_la_LIBADD = $(top_builddir)/src/lib/exceptions/libkea-exceptions.la CLEANFILES = *.gcno *.gcda diff --git a/src/lib/util/tests/Makefile.am b/src/lib/util/tests/Makefile.am index 1504aef919..e2e95f7d83 100644 --- a/src/lib/util/tests/Makefile.am +++ b/src/lib/util/tests/Makefile.am @@ -47,12 +47,11 @@ run_unittests_SOURCES += strutil_unittest.cc run_unittests_SOURCES += time_utilities_unittest.cc run_unittests_SOURCES += range_utilities_unittest.cc run_unittests_SOURCES += signal_set_unittest.cc +run_unittests_SOURCES += unix_socket_unittest.cc run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES) run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS) -#4o6 -run_unittests_SOURCES += ipc_unittest.cc run_unittests_LDADD = $(top_builddir)/src/lib/util/libkea-util.la run_unittests_LDADD += $(top_builddir)/src/lib/util/io/libkea-util-io.la run_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.la diff --git a/src/lib/util/tests/ipc_unittest.cc b/src/lib/util/tests/unix_socket_unittest.cc similarity index 65% rename from src/lib/util/tests/ipc_unittest.cc rename to src/lib/util/tests/unix_socket_unittest.cc index 6ba0cf6afe..f03ffb77f7 100644 --- a/src/lib/util/tests/ipc_unittest.cc +++ b/src/lib/util/tests/unix_socket_unittest.cc @@ -13,7 +13,7 @@ // PERFORMANCE OF THIS SOFTWARE. -#include +#include #include @@ -22,40 +22,40 @@ using namespace isc::util; namespace { -/// @brief A test fixture class for BaseIPC. -class IPCTest : public ::testing::Test { +/// @brief A test fixture class for UnixSocket. +class UnixSocketTest : public ::testing::Test { public: /// @brief Constructor. /// - /// It initializes 2 BaseIPC objects. - IPCTest() : - ipc1("test_ipc_2to1", "test_ipc_1to2"), - ipc2("test_ipc_1to2", "test_ipc_2to1") + /// It initializes 2 unix sockets. + UnixSocketTest() : + sock1_("test_ipc_2to1", "test_ipc_1to2"), + sock2_("test_ipc_1to2", "test_ipc_2to1") { } protected: - /// BaseIPC objects for testing. - BaseIPC ipc1, ipc2; + /// UnixSocket objects for testing. + UnixSocket sock1_, sock2_; }; -// Test BaseIPC constructor -TEST_F(IPCTest, constructor) { - EXPECT_EQ(-1, ipc1.getSocket()); +// Test UnixSocket constructor +TEST_F(UnixSocketTest, constructor) { + EXPECT_EQ(-1, sock1_.getSocket()); } // Test openSocket function -TEST_F(IPCTest, openSocket) { +TEST_F(UnixSocketTest, openSocket) { int fd; EXPECT_NO_THROW( - fd = ipc1.open(); + fd = sock1_.open(); ); - EXPECT_EQ(fd, ipc1.getSocket()); + EXPECT_EQ(fd, sock1_.getSocket()); } -// Test BaseIPC bidirectional data sending and receiving -TEST_F(IPCTest, bidirectionalTransmission) { +// Test bidirectional data sending and receiving. +TEST_F(UnixSocketTest, bidirectionalTransmission) { const int LEN1 = 100; const int LEN2 = 200; uint8_t data1[LEN2]; @@ -67,28 +67,28 @@ TEST_F(IPCTest, bidirectionalTransmission) { data2[i] = -i; } EXPECT_NO_THROW( - ipc1.open(); + sock1_.open(); ); EXPECT_NO_THROW( - ipc2.open(); + sock2_.open(); ); OutputBuffer sendbuf1(LEN1), sendbuf2(LEN2); sendbuf1.writeData((void*)data1, LEN1); sendbuf2.writeData((void*)data2, LEN2); EXPECT_NO_THROW( - ipc1.send(sendbuf1); + sock1_.send(sendbuf1); ); EXPECT_NO_THROW( - ipc2.send(sendbuf2); + sock2_.send(sendbuf2); ); InputBuffer recvbuf1(0, 0), recvbuf2(0, 0); EXPECT_NO_THROW( - recvbuf1 = ipc1.recv(); + recvbuf1 = sock1_.recv(); ); EXPECT_NO_THROW( - recvbuf2 = ipc2.recv(); + recvbuf2 = sock2_.recv(); ); size_t len1 = recvbuf1.getLength(); @@ -109,21 +109,21 @@ TEST_F(IPCTest, bidirectionalTransmission) { } // Test exceptions -TEST_F(IPCTest, exceptions) { +TEST_F(UnixSocketTest, exceptions) { EXPECT_THROW( - ipc1.recv(), - IPCRecvError + sock1_.recv(), + UnixSocketRecvError ); EXPECT_THROW( - ipc1.send(OutputBuffer(10)), - IPCSendError + sock1_.send(OutputBuffer(10)), + UnixSocketSendError ); EXPECT_NO_THROW( - ipc1.open(); - ipc2.open(); + sock1_.open(); + sock2_.open(); ); EXPECT_NO_THROW( - ipc1.send(OutputBuffer(10)) + sock1_.send(OutputBuffer(10)) ); } diff --git a/src/lib/util/unix_socket.cc b/src/lib/util/unix_socket.cc new file mode 100644 index 0000000000..e5c1021187 --- /dev/null +++ b/src/lib/util/unix_socket.cc @@ -0,0 +1,107 @@ +// Copyright (C) 2014 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. + +#include + +namespace isc { +namespace util { + +UnixSocket::UnixSocket(const std::string& local_filename, const std::string& remote_filename) : + socketfd_(-1), + remote_addr_len_(0), + local_filename_(local_filename), + remote_filename_(remote_filename) +{ +} + +UnixSocket::~UnixSocket() { + closeIPC(); +} + +int +UnixSocket::open() { + //create socket + int fd = socket(AF_UNIX, SOCK_DGRAM, 0); + if (fd < 0) { + isc_throw(UnixSocketOpenError, "Failed to create a socket"); + } + socketfd_ = fd; + + bindSocket(); + setRemoteFilename(); + + return socketfd_; +} + +void +UnixSocket::closeIPC() { + if(socketfd_ >= 0) + close(socketfd_); + socketfd_ = -1; +} + +int +UnixSocket::send(const isc::util::OutputBuffer &buf) { + if (remote_addr_len_ == 0) { + isc_throw(UnixSocketSendError, "Remote address unset"); + } + int count = sendto(socketfd_, buf.getData(), buf.getLength(), 0, + (struct sockaddr*)&remote_addr_, remote_addr_len_); + if (count < 0) { + isc_throw(UnixSocketSendError, "UnixSocket failed on sendto: " + << strerror(errno)); + } + return count; +} + +isc::util::InputBuffer +UnixSocket::recv() { + uint8_t buf[RCVBUFSIZE]; + int len = recvfrom(socketfd_, buf, RCVBUFSIZE, 0, NULL, NULL); + if (len < 0) { + isc_throw(UnixSocketRecvError, "UnixSocket failed on recvfrom: " + << strerror(errno)); + } + isc::util::InputBuffer ibuf(buf, len); + return ibuf; +} + +void +UnixSocket::setRemoteFilename() { + memset(&remote_addr_, 0, sizeof(struct sockaddr_un)); + remote_addr_.sun_family = AF_UNIX; + strcpy(&remote_addr_.sun_path[1], remote_filename_.c_str()); + remote_addr_len_ = sizeof(sa_family_t) + remote_filename_.size() + 1; +} + +void +UnixSocket::bindSocket() { + struct sockaddr_un local_addr_; + int local_addr_len_; + + //init address + memset(&local_addr_, 0, sizeof(struct sockaddr_un)); + local_addr_.sun_family = AF_UNIX; + strcpy(&local_addr_.sun_path[1], local_filename_.c_str()); + local_addr_len_ = sizeof(sa_family_t) + local_filename_.size() + 1; + + //bind to local_address + if (bind(socketfd_, (struct sockaddr *)&local_addr_, local_addr_len_) < 0) { + isc_throw(UnixSocketOpenError, "failed to bind to local address: " + local_filename_); + } +} + + +} +} diff --git a/src/lib/util/ipc.h b/src/lib/util/unix_socket.h similarity index 56% rename from src/lib/util/ipc.h rename to src/lib/util/unix_socket.h index eb617c8111..75dbc5ab03 100644 --- a/src/lib/util/ipc.h +++ b/src/lib/util/unix_socket.h @@ -12,8 +12,8 @@ // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // PERFORMANCE OF THIS SOFTWARE. -#ifndef IPC_H -#define IPC_H +#ifndef UNIX_SOCKET_H +#define UNIX_SOCKET_H #include #include @@ -26,23 +26,23 @@ namespace isc { namespace util { /// @brief Exception thrown when BaseIPC::open() failed. -class IPCOpenError : public Exception { +class UnixSocketOpenError : public Exception { public: - IPCOpenError(const char* file, size_t line, const char* what) : + UnixSocketOpenError(const char* file, size_t line, const char* what) : isc::Exception(file, line, what) { }; }; -/// @brief Exception thrown when BaseIPC::recv() failed. -class IPCRecvError : public Exception { +/// @brief Exception thrown when UnixSocket::recv() failed. +class UnixSocketRecvError : public Exception { public: - IPCRecvError(const char* file, size_t line, const char* what) : + UnixSocketRecvError(const char* file, size_t line, const char* what) : isc::Exception(file, line, what) { }; }; /// @brief Exception thrown when BaseIPC::send() failed. -class IPCSendError : public Exception { +class UnixSocketSendError : public Exception { public: - IPCSendError(const char* file, size_t line, const char* what) : + UnixSocketSendError(const char* file, size_t line, const char* what) : isc::Exception(file, line, what) { }; }; @@ -57,7 +57,7 @@ public: /// /// It should be used as a base class and not directly used for future classes /// implementing inter process communication. -class BaseIPC { +class UnixSocket { public: /// @brief Packet reception buffer size @@ -72,18 +72,11 @@ public: /// /// @param local_filename Filename for receiving socket /// @param remote_filename Filename for sending socket - BaseIPC(const std::string& local_filename, const std::string& remote_filename) : - socketfd_(-1), - remote_addr_len_(0), - local_filename_(local_filename), - remote_filename_(remote_filename) - { - } - + UnixSocket(const std::string& local_filename, const std::string& remote_filename); /// @brief BaseIPC destructor. /// /// It closes the socket explicitly. - virtual ~BaseIPC() { closeIPC(); } + virtual ~UnixSocket(); /// @brief Open UNIX socket @@ -91,26 +84,10 @@ public: /// Method will throw if socket creation fails. /// /// @return A int value of the socket descriptor. - int open() { - //create socket - int fd = socket(AF_UNIX, SOCK_DGRAM, 0); - if (fd < 0) { - isc_throw(IPCOpenError, "Failed to create a socket"); - } - socketfd_ = fd; - - bindSocket(); - setRemoteFilename(); - - return socketfd_; - } + int open(); /// @brief Close opened socket. - void closeIPC() { - if(socketfd_ >= 0) - close(socketfd_); - socketfd_ = -1; - } + void closeIPC(); /// @brief Send data. /// @@ -120,18 +97,7 @@ public: /// open() MUST be called before calling this function. /// /// @return The number of bytes sent. - int send(const isc::util::OutputBuffer &buf) { - if (remote_addr_len_ == 0) { - isc_throw(IPCSendError, "Remote address unset"); - } - int count = sendto(socketfd_, buf.getData(), buf.getLength(), 0, - (struct sockaddr*)&remote_addr_, remote_addr_len_); - if (count < 0) { - isc_throw(IPCSendError, "BaseIPC failed on sendto: " - << strerror(errno)); - } - return count; - } + int send(const isc::util::OutputBuffer &buf); /// @brief Receive data. /// @@ -139,16 +105,7 @@ public: /// open() MUST be called before calling this function. /// /// @return The number of bytes received. - isc::util::InputBuffer recv() { - uint8_t buf[RCVBUFSIZE]; - int len = recvfrom(socketfd_, buf, RCVBUFSIZE, 0, NULL, NULL); - if (len < 0) { - isc_throw(IPCRecvError, "BaseIPC failed on recvfrom: " - << strerror(errno)); - } - isc::util::InputBuffer ibuf(buf, len); - return ibuf; - } + isc::util::InputBuffer recv(); /// @brief Get socket fd. /// @@ -161,33 +118,14 @@ protected: /// /// The remote filename is used for sending data. The filename is given /// in the constructor. - void setRemoteFilename() { - memset(&remote_addr_, 0, sizeof(struct sockaddr_un)); - remote_addr_.sun_family = AF_UNIX; - strcpy(&remote_addr_.sun_path[1], remote_filename_.c_str()); - remote_addr_len_ = sizeof(sa_family_t) + remote_filename_.size() + 1; - } + void setRemoteFilename(); /// @brief Bind the UNIX socket to the given filename /// /// The filename is given in the constructor. /// /// Method will throw if socket binding fails. - void bindSocket() { - struct sockaddr_un local_addr_; - int local_addr_len_; - - //init address - memset(&local_addr_, 0, sizeof(struct sockaddr_un)); - local_addr_.sun_family = AF_UNIX; - strcpy(&local_addr_.sun_path[1], local_filename_.c_str()); - local_addr_len_ = sizeof(sa_family_t) + local_filename_.size() + 1; - - //bind to local_address - if (bind(socketfd_, (struct sockaddr *)&local_addr_, local_addr_len_) < 0) { - isc_throw(IPCOpenError, "failed to bind to local address: " + local_filename_); - } - } + void bindSocket(); /// UNIX socket value. int socketfd_; @@ -201,9 +139,10 @@ protected: /// Filename for receiving and sending socket std::string local_filename_, remote_filename_; -}; // BaseIPC class +}; // UnixSocket class } // namespace util } // namespace isc -#endif // IPC_H + +#endif // UNIX_SOCKET_H