From 8054e34e967eecd303ecacd5c745f71bf4c5961d Mon Sep 17 00:00:00 2001 From: Ingo Fischer Date: Fri, 1 Dec 2023 13:39:20 +0100 Subject: [PATCH] Respect UDP packet maximum size (#551) and do not process bigger messages --- .../matter-node.js/src/net/UdpChannelNode.ts | 19 ++++++++++++++++++- packages/matter.js/src/spec/Specifications.ts | 9 +++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/packages/matter-node.js/src/net/UdpChannelNode.ts b/packages/matter-node.js/src/net/UdpChannelNode.ts index fb922bcddd..f12ed76532 100644 --- a/packages/matter-node.js/src/net/UdpChannelNode.ts +++ b/packages/matter-node.js/src/net/UdpChannelNode.ts @@ -6,11 +6,14 @@ import { Logger } from "@project-chip/matter.js/log"; import { NetworkError, UdpChannel, UdpChannelOptions } from "@project-chip/matter.js/net"; +import { MatterCoreSpecificationV1_2 } from "@project-chip/matter.js/spec"; import { ByteArray } from "@project-chip/matter.js/util"; - import * as dgram from "dgram"; import { NetworkNode } from "./NetworkNode.js"; +/** @see {@link MatterCoreSpecificationV1_2} ยง 4.4.4 */ +const MAX_UDP_PAYLOAD_SIZE = 1280; + const logger = Logger.get("UdpChannelNode"); function createDgramSocket(host: string | undefined, port: number | undefined, options: dgram.SocketOptions) { @@ -102,6 +105,12 @@ export class UdpChannelNode implements UdpChannel { onData(listener: (netInterface: string, peerAddress: string, peerPort: number, data: ByteArray) => void) { const messageListener = (data: ByteArray, { address, port }: dgram.RemoteInfo) => { + if (data.length > MAX_UDP_PAYLOAD_SIZE) { + logger.warn( + `Ignoring UDP message with size ${data.length} from ${address}:${port}, which is larger than the maximum allowed size of ${MAX_UDP_PAYLOAD_SIZE}.`, + ); + return; + } const netInterface = this.netInterface ?? NetworkNode.getNetInterfaceForIp(address); if (netInterface === undefined) return; listener(netInterface, address, port, data); @@ -117,6 +126,14 @@ export class UdpChannelNode implements UdpChannel { async send(host: string, port: number, data: ByteArray) { return new Promise((resolve, reject) => { + if (data.length > MAX_UDP_PAYLOAD_SIZE) { + reject( + new NetworkError( + `Cannot send UDP message with size ${data.length}, which is larger than the maximum allowed size of ${MAX_UDP_PAYLOAD_SIZE}.`, + ), + ); + return; + } this.socket.send(data, port, host, error => { if (error !== null) { reject(error); diff --git a/packages/matter.js/src/spec/Specifications.ts b/packages/matter.js/src/spec/Specifications.ts index 2d0d368fe3..b873bba092 100644 --- a/packages/matter.js/src/spec/Specifications.ts +++ b/packages/matter.js/src/spec/Specifications.ts @@ -21,3 +21,12 @@ export interface MatterApplicationClusterSpecificationV1_1 {} /** {@link https://csa-iot.org/developer-resource/specifications-download-request/ Matter Device Library Specification 1.1} */ export interface MatterDeviceLibrarySpecificationV1_1 {} + +/** {@link https://csa-iot.org/developer-resource/specifications-download-request/ Matter Core Specification 1.2} */ +export interface MatterCoreSpecificationV1_2 {} + +/** {@link https://csa-iot.org/developer-resource/specifications-download-request/ Matter Application Cluster Specification 1.2} */ +export interface MatterApplicationClusterSpecificationV1_2 {} + +/** {@link https://csa-iot.org/developer-resource/specifications-download-request/ Matter Device Library Specification 1.2} */ +export interface MatterDeviceLibrarySpecificationV1_2 {}