| Kea 3.0.2-git

pkt_filter.cc
Go to the documentation of this file.
1// Copyright (C) 2013-2024 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
18 PktFilter::openFallbackSocket(const isc::asiolink::IOAddress& addr,
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} // end of isc::dhcp namespace
71} // end of isc namespace
isc::asiolink::IOAddress
The IOAddress class represents an IP addresses (version agnostic).
Definition io_address.h:45
isc::asiolink::IOAddress::toUint32
uint32_t toUint32() const
Converts IPv4 address to uint32_t.
Definition io_address.cc:121
isc::dhcp::PktFilter::openFallbackSocket
virtual int openFallbackSocket(const isc::asiolink::IOAddress &addr, const uint16_t port)
Default implementation to open a fallback socket.
Definition pkt_filter.cc:18
isc::dhcp::SocketConfigError
IfaceMgr exception thrown thrown when socket opening or configuration failed.
Definition iface_mgr.h:63
isc_throw
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Definition exceptions/exceptions.h:210
iface_mgr.h
isc::dhcp
Definition dhcp4/client_handler.cc:20
isc
Defines the logger used by the top-level component of kea-lfc.
Definition agent_parser.cc:148
pkt_filter.h