Kea  2.1.6-git
pkt_filter.cc
Go to the documentation of this file.
1 // Copyright (C) 2013-2019 Internet Systems Consortium, Inc. ("ISC")
2 //
3 // This Source Code Form is subject to the terms of the Mozilla Public
4 // License, v. 2.0. If a copy of the MPL was not distributed with this
5 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 
7 #include <config.h>
8 #include <dhcp/iface_mgr.h>
9 #include <dhcp/pkt_filter.h>
10 
11 #include <sys/socket.h>
12 #include <fcntl.h>
13 
14 namespace isc {
15 namespace dhcp {
16 
17 int
19  const uint16_t port) {
20  // Create socket.
21  int sock = socket(AF_INET, SOCK_DGRAM, 0);
22  if (sock < 0) {
23  isc_throw(SocketConfigError, "failed to create fallback socket for"
24  " address " << addr << ", port " << port
25  << ", reason: " << strerror(errno));
26  }
27  // Set the close-on-exec flag.
28  if (fcntl(sock, F_SETFD, FD_CLOEXEC) < 0) {
29  close(sock);
30  isc_throw(SocketConfigError, "Failed to set close-on-exec flag"
31  << " on fallback socket for address " << addr
32  << ", port " << port
33  << ", reason: " << strerror(errno));
34  }
35  // Bind the socket to a specified address and port.
36  struct sockaddr_in addr4;
37  memset(&addr4, 0, sizeof(addr4));
38  addr4.sin_family = AF_INET;
39  addr4.sin_addr.s_addr = htonl(addr.toUint32());
40  addr4.sin_port = htons(port);
41 
42  if (bind(sock, reinterpret_cast<struct sockaddr*>(&addr4),
43  sizeof(addr4)) < 0) {
44  // Get the error message immediately after the bind because the
45  // invocation to close() below would override the errno.
46  char* errmsg = strerror(errno);
47  // Remember to close the socket if we failed to bind it.
48  close(sock);
49  isc_throw(SocketConfigError, "failed to bind fallback socket to"
50  " address " << addr << ", port " << port
51  << ", reason: " << errmsg
52  << " - is another DHCP server running?");
53  }
54 
55  // Set socket to non-blocking mode. This is to prevent the read from the
56  // fallback socket to block message processing on the primary socket.
57  if (fcntl(sock, F_SETFL, O_NONBLOCK) != 0) {
58  // Get the error message immediately after the bind because the
59  // invocation to close() below would override the errno.
60  char* errmsg = strerror(errno);
61  close(sock);
62  isc_throw(SocketConfigError, "failed to set SO_NONBLOCK option on the"
63  " fallback socket, bound to " << addr << ", port "
64  << port << ", reason: " << errmsg);
65  }
66  // Successfully created and bound a fallback socket. Return a descriptor.
67  return (sock);
68 }
69 
70 
71 } // end of isc::dhcp namespace
72 } // end of isc namespace
IfaceMgr exception thrown thrown when socket opening or configuration failed.
Definition: iface_mgr.h:63
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Defines the logger used by the top-level component of kea-lfc.
virtual int openFallbackSocket(const isc::asiolink::IOAddress &addr, const uint16_t port)
Default implementation to open a fallback socket.
Definition: pkt_filter.cc:18