sd-dhcp-client: eagerly drop too small packets
If they are too small to fit the IP+UDP+DHCP headers they can be of no use, so don't waste resources parsing them. This is at the cost of losing some verbosity in the logging.
This commit is contained in:
@@ -34,11 +34,14 @@
|
||||
int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link)
|
||||
{
|
||||
struct sock_filter filter[] = {
|
||||
BPF_STMT(BPF_LD + BPF_W + BPF_LEN, 0), /* A <- packet length */
|
||||
BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, sizeof(DHCPPacket), 1, 0), /* packet >= DHCPPacket ? */
|
||||
BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
|
||||
BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, ip.protocol)), /* A <- IP protocol */
|
||||
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 1, 0), /* IP protocol = UDP? */
|
||||
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 1, 0), /* IP protocol == UDP ? */
|
||||
BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
|
||||
BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(DHCPPacket, udp.dest)), /* A <- UDP destination port */
|
||||
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, DHCP_PORT_CLIENT, 1, 0), /* UDP destination port = DHCP client? */
|
||||
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, DHCP_PORT_CLIENT, 1, 0), /* UDP destination port == DHCP client port ? */
|
||||
BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
|
||||
BPF_STMT(BPF_RET + BPF_K, 65535), /* return all */
|
||||
};
|
||||
|
||||
@@ -113,13 +113,6 @@ int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum) {
|
||||
|
||||
/* IP */
|
||||
|
||||
if (len < DHCP_IP_SIZE) {
|
||||
log_dhcp_client(client, "ignoring packet: packet (%zu bytes) "
|
||||
" smaller than IP header (%u bytes)", len,
|
||||
DHCP_IP_SIZE);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (packet->ip.version != IPVERSION) {
|
||||
log_dhcp_client(client, "ignoring packet: not IPv4");
|
||||
return -EINVAL;
|
||||
@@ -152,13 +145,6 @@ int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (len < DHCP_IP_UDP_SIZE) {
|
||||
log_dhcp_client(client, "ignoring packet: packet (%zu bytes) "
|
||||
" smaller than IP+UDP header (%u bytes)", len,
|
||||
DHCP_IP_UDP_SIZE);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (len < hdrlen + be16toh(packet->udp.len)) {
|
||||
log_dhcp_client(client, "ignoring packet: packet (%zu bytes) "
|
||||
"smaller than expected (%zu) by UDP header", len,
|
||||
|
||||
@@ -931,12 +931,6 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message,
|
||||
assert(client->event);
|
||||
assert(message);
|
||||
|
||||
if (len < DHCP_MESSAGE_SIZE) {
|
||||
log_dhcp_client(client, "message too small (%d bytes): "
|
||||
"ignoring", len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (be32toh(message->magic) != DHCP_MAGIC_COOKIE) {
|
||||
log_dhcp_client(client, "not a DHCP message: ignoring");
|
||||
return 0;
|
||||
@@ -1081,7 +1075,11 @@ static int client_receive_message_udp(sd_event_source *s, int fd,
|
||||
return -ENOMEM;
|
||||
|
||||
len = read(fd, message, buflen);
|
||||
if (len < 0)
|
||||
if (len < 0) {
|
||||
log_dhcp_client(client, "could not receive message from UDP "
|
||||
"socket: %s", strerror(errno));
|
||||
return 0;
|
||||
} else if ((size_t)len < sizeof(DHCPMessage))
|
||||
return 0;
|
||||
|
||||
return client_handle_message(client, message, len);
|
||||
@@ -1122,7 +1120,8 @@ static int client_receive_message_raw(sd_event_source *s, int fd,
|
||||
log_dhcp_client(client, "could not receive message from raw "
|
||||
"socket: %s", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
} else if ((size_t)len < sizeof(DHCPPacket))
|
||||
return 0;
|
||||
|
||||
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
|
||||
if (cmsg->cmsg_level == SOL_PACKET && cmsg->cmsg_type == PACKET_AUXDATA) {
|
||||
|
||||
Reference in New Issue
Block a user