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
64513e31c0
This commit is contained in:

committed by
Thomas Haller

parent
197e73ac7c
commit
a5a5654f18
@@ -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;
|
||||
|
@@ -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) { \
|
||||
|
Reference in New Issue
Block a user