From: Francis Dupont Date: Mon, 10 Dec 2018 08:06:50 +0000 (+0100) Subject: [327-split-transmission-and-reception-control-buffers] Reported dhcp library part... X-Git-Tag: 343-put-socket-control-buffer-in-the-stack_base~17 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fd2bb674dd0b6074164e98d6b2c367d7e9905123;p=thirdparty%2Fkea.git [327-split-transmission-and-reception-control-buffers] Reported dhcp library part of !135 --- diff --git a/src/lib/dhcp/iface_mgr.cc b/src/lib/dhcp/iface_mgr.cc index d2e32d2233..1cf2e39c78 100644 --- a/src/lib/dhcp/iface_mgr.cc +++ b/src/lib/dhcp/iface_mgr.cc @@ -180,9 +180,7 @@ bool Iface::delSocket(const uint16_t sockfd) { } IfaceMgr::IfaceMgr() - :control_buf_len_(CMSG_SPACE(sizeof(struct in6_pktinfo))), - control_buf_(new char[control_buf_len_]), - packet_filter_(new PktFilterInet()), + :packet_filter_(new PktFilterInet()), packet_filter6_(new PktFilterInet6()), test_mode_(false), allow_loopback_(false) { @@ -307,9 +305,6 @@ void IfaceMgr::stopDHCPReceiver() { } IfaceMgr::~IfaceMgr() { - // control_buf_ is deleted automatically (scoped_ptr) - control_buf_len_ = 0; - closeSockets(); } @@ -506,13 +501,26 @@ IfaceMgr::openSockets4(const uint16_t port, const bool use_bcast, } + if (!iface->flag_up_) { + IFACEMGR_ERROR(SocketConfigError, error_handler, + "the interface " << iface->getName() + << " is down"); + continue; + } + + if (!iface->flag_running_) { + IFACEMGR_ERROR(SocketConfigError, error_handler, + "the interface " << iface->getName() + << " is not running"); + continue; + } + IOAddress out_address("0.0.0.0"); if (!iface->flag_up_ || !iface->flag_running_ || !iface->getAddress4(out_address)) { IFACEMGR_ERROR(SocketConfigError, error_handler, "the interface " << iface->getName() - << " is down or has no usable IPv4" - " addresses configured"); + << " has no usable IPv4 addresses configured"); continue; } } @@ -618,11 +626,15 @@ IfaceMgr::openSockets6(const uint16_t port, " interface " << iface->getName()); continue; - } else if (!iface->flag_up_ || !iface->flag_running_) { + } else if (!iface->flag_up_) { + IFACEMGR_ERROR(SocketConfigError, error_handler, + "the interface " << iface->getName() + << " is down"); + continue; + } else if (!iface->flag_running_) { IFACEMGR_ERROR(SocketConfigError, error_handler, "the interface " << iface->getName() - << " is down or has no usable IPv6" - " addresses configured"); + << " is not running"); continue; } diff --git a/src/lib/dhcp/iface_mgr.h b/src/lib/dhcp/iface_mgr.h index 3bc7ff0dbc..e771ce2764 100644 --- a/src/lib/dhcp/iface_mgr.h +++ b/src/lib/dhcp/iface_mgr.h @@ -1255,12 +1255,6 @@ protected: // is bound to multicast address. And we all know what happens // to people who try to use multicast as source address. - /// Length of the control_buf_ array - size_t control_buf_len_; - - /// Control-buffer, used in transmission and reception. - boost::scoped_array control_buf_; - private: /// @brief Identifies local network address to be used to /// connect to remote address. diff --git a/src/lib/dhcp/pkt_filter_inet.cc b/src/lib/dhcp/pkt_filter_inet.cc index 4311caafac..9953e8780c 100644 --- a/src/lib/dhcp/pkt_filter_inet.cc +++ b/src/lib/dhcp/pkt_filter_inet.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2017 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2013-2018 Internet Systems Consortium, Inc. ("ISC") // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -18,8 +18,10 @@ namespace isc { namespace dhcp { PktFilterInet::PktFilterInet() - : control_buf_len_(CMSG_SPACE(sizeof(struct in6_pktinfo))), - control_buf_(new char[control_buf_len_]) + : recv_control_buf_len_(CMSG_SPACE(sizeof(struct in6_pktinfo))), + send_control_buf_len_(CMSG_SPACE(sizeof(struct in6_pktinfo))), + recv_control_buf_(new char[recv_control_buf_len_]), + send_control_buf_(new char[send_control_buf_len_]) { } @@ -112,7 +114,7 @@ PktFilterInet::receive(Iface& iface, const SocketInfo& socket_info) { struct sockaddr_in from_addr; uint8_t buf[IfaceMgr::RCVBUFSIZE]; - memset(&control_buf_[0], 0, control_buf_len_); + memset(&recv_control_buf_[0], 0, recv_control_buf_len_); memset(&from_addr, 0, sizeof(from_addr)); // Initialize our message header structure. @@ -135,8 +137,8 @@ PktFilterInet::receive(Iface& iface, const SocketInfo& socket_info) { // previously asked the kernel to give us packet // information (when we initialized the interface), so we // should get the destination address from that. - m.msg_control = &control_buf_[0]; - m.msg_controllen = control_buf_len_; + m.msg_control = &recv_control_buf_[0]; + m.msg_controllen = recv_control_buf_len_; int result = recvmsg(socket_info.sockfd_, &m, 0); if (result < 0) { @@ -211,7 +213,7 @@ PktFilterInet::receive(Iface& iface, const SocketInfo& socket_info) { int PktFilterInet::send(const Iface&, uint16_t sockfd, const Pkt4Ptr& pkt) { - memset(&control_buf_[0], 0, control_buf_len_); + memset(&send_control_buf_[0], 0, send_control_buf_len_); // Set the target address we're sending to. sockaddr_in to; @@ -247,8 +249,8 @@ PktFilterInet::send(const Iface&, uint16_t sockfd, // We have to create a "control message", and set that to // define the IPv4 packet information. We set the source address // to handle correctly interfaces with multiple addresses. - m.msg_control = &control_buf_[0]; - m.msg_controllen = control_buf_len_; + m.msg_control = &send_control_buf_[0]; + m.msg_controllen = send_control_buf_len_; struct cmsghdr* cmsg = CMSG_FIRSTHDR(&m); cmsg->cmsg_level = IPPROTO_IP; cmsg->cmsg_type = IP_PKTINFO; diff --git a/src/lib/dhcp/pkt_filter_inet.h b/src/lib/dhcp/pkt_filter_inet.h index 6cc9fecb4e..b1b6f93096 100644 --- a/src/lib/dhcp/pkt_filter_inet.h +++ b/src/lib/dhcp/pkt_filter_inet.h @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2017 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2013-2018 Internet Systems Consortium, Inc. ("ISC") // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -22,7 +22,7 @@ public: /// @brief Constructor /// - /// Allocates control buffer. + /// Allocates control buffers. PktFilterInet(); /// @brief Check if packet can be sent to the host without address directly. @@ -85,10 +85,16 @@ public: const Pkt4Ptr& pkt); private: - /// Length of the control_buf_ array. - size_t control_buf_len_; - /// Control buffer, used in transmission and reception. - boost::scoped_array control_buf_; + /// There are separate control buffers for sending and receiving to be able + /// to send and receive packets in parallel in two threads. + /// Length of the recv_control_buf_ array. + size_t recv_control_buf_len_; + /// Length of the send_control_buf_ array. + size_t send_control_buf_len_; + /// Control buffer, used in reception. + boost::scoped_array recv_control_buf_; + /// Control buffer, used in transmission. + boost::scoped_array send_control_buf_; }; } // namespace isc::dhcp diff --git a/src/lib/dhcp/pkt_filter_inet6.cc b/src/lib/dhcp/pkt_filter_inet6.cc index ba706d0361..eede050a71 100644 --- a/src/lib/dhcp/pkt_filter_inet6.cc +++ b/src/lib/dhcp/pkt_filter_inet6.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2017 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2013-2018 Internet Systems Consortium, Inc. ("ISC") // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -20,8 +20,10 @@ namespace isc { namespace dhcp { PktFilterInet6::PktFilterInet6() -: control_buf_len_(CMSG_SPACE(sizeof(struct in6_pktinfo))), - control_buf_(new char[control_buf_len_]) { +: recv_control_buf_len_(CMSG_SPACE(sizeof(struct in6_pktinfo))), + send_control_buf_len_(CMSG_SPACE(sizeof(struct in6_pktinfo))), + recv_control_buf_(new char[recv_control_buf_len_]), + send_control_buf_(new char[send_control_buf_len_]) { } SocketInfo @@ -135,7 +137,7 @@ Pkt6Ptr PktFilterInet6::receive(const SocketInfo& socket_info) { // Now we have a socket, let's get some data from it! uint8_t buf[IfaceMgr::RCVBUFSIZE]; - memset(&control_buf_[0], 0, control_buf_len_); + memset(&recv_control_buf_[0], 0, recv_control_buf_len_); struct sockaddr_in6 from; memset(&from, 0, sizeof(from)); @@ -163,8 +165,8 @@ PktFilterInet6::receive(const SocketInfo& socket_info) { // previously asked the kernel to give us packet // information (when we initialized the interface), so we // should get the destination address from that. - m.msg_control = &control_buf_[0]; - m.msg_controllen = control_buf_len_; + m.msg_control = &recv_control_buf_[0]; + m.msg_controllen = recv_control_buf_len_; int result = recvmsg(socket_info.sockfd_, &m, 0); @@ -245,7 +247,7 @@ PktFilterInet6::receive(const SocketInfo& socket_info) { int PktFilterInet6::send(const Iface&, uint16_t sockfd, const Pkt6Ptr& pkt) { - memset(&control_buf_[0], 0, control_buf_len_); + memset(&send_control_buf_[0], 0, send_control_buf_len_); // Set the target address we're sending to. sockaddr_in6 to; @@ -287,8 +289,8 @@ PktFilterInet6::send(const Iface&, uint16_t sockfd, const Pkt6Ptr& pkt) { // define the IPv6 packet information. We could set the // source address if we wanted, but we can safely let the // kernel decide what that should be. - m.msg_control = &control_buf_[0]; - m.msg_controllen = control_buf_len_; + m.msg_control = &send_control_buf_[0]; + m.msg_controllen = send_control_buf_len_; struct cmsghdr *cmsg = CMSG_FIRSTHDR(&m); // FIXME: Code below assumes that cmsg is not NULL, but diff --git a/src/lib/dhcp/pkt_filter_inet6.h b/src/lib/dhcp/pkt_filter_inet6.h index 927a077872..39a059d73d 100644 --- a/src/lib/dhcp/pkt_filter_inet6.h +++ b/src/lib/dhcp/pkt_filter_inet6.h @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2017 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2013-2018 Internet Systems Consortium, Inc. ("ISC") // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -23,7 +23,8 @@ public: /// @brief Constructor. /// - /// Initializes a control buffer used in the message transmission. + /// Initializes control buffers used in message transmission and + /// reception. PktFilterInet6(); /// @brief Opens a socket. @@ -84,10 +85,16 @@ public: const Pkt6Ptr& pkt); private: - /// Length of the control_buf_ array. - size_t control_buf_len_; - /// Control buffer, used in transmission and reception. - boost::scoped_array control_buf_; + /// There are separate control buffers for sending and receiving to be able + /// to send and receive packets in parallel in two threads. + /// Length of the recv_control_buf_ array. + size_t recv_control_buf_len_; + /// Length of the send_control_buf_ array. + size_t send_control_buf_len_; + /// Control buffer, used in reception. + boost::scoped_array recv_control_buf_; + /// Control buffer, used in transmission. + boost::scoped_array send_control_buf_; }; } // namespace isc::dhcp