summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2022-03-14 11:05:28 +0100
committerThomas Haller <thaller@redhat.com>2022-04-13 11:05:12 +0200
commit74382182100d686cc6b09641c4d434030e7de861 (patch)
tree6277544669b150aa8086dbfbb4fdcf9f468a2ea2
parent0c6d242dc0b67b6269657acf33bf9d1f0830f0b4 (diff)
n-dhcp4/connection: dynamically allocate the receive buffer
Each connection object includes a 64KiB scratch buffer used for receiving packets. When many instances of the client are created, those buffers use a significant amount of memory. For example, 500 clients take ~30MiB of memory constantly reserved only for those buffers. Since the buffer is used only in the function and is never passed outside, a stack allocation would suffice; however, it's not wise to do such large allocations on the stack; dynamically allocate it. https://github.com/nettools/n-dhcp4/issues/26 https://github.com/nettools/n-dhcp4/pull/27 https://github.com/nettools/n-dhcp4/commit/64513e31c01a88db54c89321f89bcc85da27ffc5 (cherry picked from commit a5a5654f187535d0d60f508bd44fff16f036d536)
-rw-r--r--src/n-dhcp4/src/n-dhcp4-c-connection.c17
-rw-r--r--src/n-dhcp4/src/n-dhcp4-private.h9
2 files changed, 11 insertions, 15 deletions
diff --git a/src/n-dhcp4/src/n-dhcp4-c-connection.c b/src/n-dhcp4/src/n-dhcp4-c-connection.c
index 2f660e3b30..65328286e8 100644
--- a/src/n-dhcp4/src/n-dhcp4-c-connection.c
+++ b/src/n-dhcp4/src/n-dhcp4-c-connection.c
@@ -1147,16 +1147,21 @@ int n_dhcp4_c_connection_dispatch_timer(NDhcp4CConnection *connection,
int n_dhcp4_c_connection_dispatch_io(NDhcp4CConnection *connection,
NDhcp4Incoming **messagep) {
_c_cleanup_(n_dhcp4_incoming_freep) NDhcp4Incoming *message = NULL;
+ _c_cleanup_(c_freep) uint8_t *buffer = NULL;
char serv_addr[INET_ADDRSTRLEN];
char client_addr[INET_ADDRSTRLEN];
uint8_t type = 0;
int r;
+ buffer = malloc(UINT16_MAX);
+ if (!buffer)
+ return -ENOMEM;
+
switch (connection->state) {
case N_DHCP4_C_CONNECTION_STATE_PACKET:
r = n_dhcp4_c_socket_packet_recv(connection->fd_packet,
- connection->scratch_buffer,
- sizeof(connection->scratch_buffer),
+ buffer,
+ UINT16_MAX,
&message);
if (!r)
break;
@@ -1165,8 +1170,8 @@ int n_dhcp4_c_connection_dispatch_io(NDhcp4CConnection *connection,
return N_DHCP4_E_AGAIN;
case N_DHCP4_C_CONNECTION_STATE_DRAINING:
r = n_dhcp4_c_socket_packet_recv(connection->fd_packet,
- connection->scratch_buffer,
- sizeof(connection->scratch_buffer),
+ buffer,
+ UINT16_MAX,
&message);
if (!r)
break;
@@ -1188,8 +1193,8 @@ int n_dhcp4_c_connection_dispatch_io(NDhcp4CConnection *connection,
/* fall-through */
case N_DHCP4_C_CONNECTION_STATE_UDP:
r = n_dhcp4_c_socket_udp_recv(connection->fd_udp,
- connection->scratch_buffer,
- sizeof(connection->scratch_buffer),
+ buffer,
+ UINT16_MAX,
&message);
if (!r)
break;
diff --git a/src/n-dhcp4/src/n-dhcp4-private.h b/src/n-dhcp4/src/n-dhcp4-private.h
index 191e946e70..858c3d3ab0 100644
--- a/src/n-dhcp4/src/n-dhcp4-private.h
+++ b/src/n-dhcp4/src/n-dhcp4-private.h
@@ -334,15 +334,6 @@ struct NDhcp4CConnection {
uint32_t client_ip; /* client IP address, or 0 */
uint32_t server_ip; /* server IP address, or 0 */
uint16_t mtu; /* client mtu, or 0 */
-
- /*
- * When we get DHCP packets from the kernel, we need a buffer to read
- * the data into. Since UDP packets can be up to 2^16 bytes in size, we
- * avoid placing it on the stack and instead read into this scratch
- * buffer. It is purely meant as stack replacement, no data is returned
- * through this buffer.
- */
- uint8_t scratch_buffer[UINT16_MAX];
};
#define N_DHCP4_C_CONNECTION_NULL(_x) { \