diff options
Diffstat (limited to 'src/n-dhcp4')
| -rw-r--r-- | src/n-dhcp4/src/n-dhcp4-c-connection.c | 36 | ||||
| -rw-r--r-- | src/n-dhcp4/src/n-dhcp4-c-probe.c | 3 | ||||
| -rw-r--r-- | src/n-dhcp4/src/n-dhcp4-private.h | 10 |
3 files changed, 32 insertions, 17 deletions
diff --git a/src/n-dhcp4/src/n-dhcp4-c-connection.c b/src/n-dhcp4/src/n-dhcp4-c-connection.c index 4aba9739..65328286 100644 --- a/src/n-dhcp4/src/n-dhcp4-c-connection.c +++ b/src/n-dhcp4/src/n-dhcp4-c-connection.c @@ -705,6 +705,7 @@ int n_dhcp4_c_connection_select_new(NDhcp4CConnection *connection, message->userdata.start_time = offer->userdata.start_time; message->userdata.base_time = offer->userdata.base_time; message->userdata.client_addr = client.s_addr; + message->userdata.server_id = server.s_addr; n_dhcp4_incoming_get_xid(offer, &xid); n_dhcp4_outgoing_set_xid(message, xid); @@ -1146,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; @@ -1164,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; @@ -1187,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; @@ -1224,6 +1230,24 @@ int n_dhcp4_c_connection_dispatch_io(NDhcp4CConnection *connection, serv_addr, sizeof(serv_addr))); } + if (type == N_DHCP4_MESSAGE_NAK && + connection->request->userdata.server_id != INADDR_ANY) { + struct in_addr server; + + r = n_dhcp4_incoming_query_server_identifier(message, &server); + if (r) + return N_DHCP4_E_AGAIN; + + if (connection->request->userdata.server_id != server.s_addr) { + n_dhcp4_log(connection->log_queue, + LOG_DEBUG, + "discarded NAK with wrong server-id %s", + inet_ntop(AF_INET, &server, + serv_addr, sizeof(serv_addr))); + return N_DHCP4_E_AGAIN; + } + } + switch (type) { case N_DHCP4_MESSAGE_OFFER: case N_DHCP4_MESSAGE_ACK: diff --git a/src/n-dhcp4/src/n-dhcp4-c-probe.c b/src/n-dhcp4/src/n-dhcp4-c-probe.c index 7f20ac05..283c1693 100644 --- a/src/n-dhcp4/src/n-dhcp4-c-probe.c +++ b/src/n-dhcp4/src/n-dhcp4-c-probe.c @@ -995,14 +995,13 @@ static int n_dhcp4_client_probe_transition_nak(NDhcp4ClientProbe *probe) { case N_DHCP4_CLIENT_PROBE_STATE_RENEWING: case N_DHCP4_CLIENT_PROBE_STATE_REBINDING: - /* XXX */ - r = n_dhcp4_client_probe_raise(probe, NULL, N_DHCP4_CLIENT_EVENT_RETRACTED); if (r) return r; + probe->current_lease = n_dhcp4_client_lease_unref(probe->current_lease); probe->state = N_DHCP4_CLIENT_PROBE_STATE_INIT; probe->ns_deferred = n_dhcp4_gettime(CLOCK_BOOTTIME) + probe->ns_nak_restart_delay; probe->ns_nak_restart_delay = C_CLAMP(probe->ns_nak_restart_delay * 2u, diff --git a/src/n-dhcp4/src/n-dhcp4-private.h b/src/n-dhcp4/src/n-dhcp4-private.h index db7b24ff..858c3d3a 100644 --- a/src/n-dhcp4/src/n-dhcp4-private.h +++ b/src/n-dhcp4/src/n-dhcp4-private.h @@ -202,6 +202,7 @@ struct NDhcp4Outgoing { uint8_t type; uint8_t message_type; uint32_t client_addr; + uint32_t server_id; uint64_t start_time; uint64_t base_time; uint64_t send_time; @@ -333,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) { \ |