]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
sdp: parse time and repeat_time multiple times
authorGiuseppe Longo <giuseppe@glongo.it>
Tue, 15 Oct 2024 04:39:18 +0000 (06:39 +0200)
committerVictor Julien <victor@inliniac.net>
Wed, 2 Apr 2025 20:36:16 +0000 (22:36 +0200)
As defined in RFC4566, the time and repeat_time fields can be present
multiple times but they are currently parsed only once.

Ticket #7325

etc/schema.json
rust/src/sdp/logger.rs
rust/src/sdp/parser.rs

index 901b964a395d4484585044c051d6e9e448196e6f..f0a8ba5af9ffcc3ce53b248ef59c2669191b234b 100644 (file)
                                 "type": "string"
                             }
                         },
-                        "time": {
-                            "type": "string",
-                            "optional": true,
-                            "description": "Start and stop times for a session"
-                        },
-                        "repeat_time": {
-                            "type": "string",
-                            "optional": true,
-                            "description": "Specify repeat times for a session"
+                        "time_descriptions": {
+                            "type": "array",
+                            "description": "A list of time descriptions for a session",
+                            "minItems": 1,
+                            "items": {
+                                "type": "object",
+                                "optional": true,
+                                "properties": {
+                                    "time": {
+                                        "type": "string",
+                                        "optional": true,
+                                        "description": "Start and stop times for a session"
+                                    },
+                                    "repeat_time": {
+                                        "type": "string",
+                                        "optional": true,
+                                        "description": "Specify repeat times for a session"
+                                    }
+                                },
+                                "additionalProperties": false
+                            }
                         },
                         "timezone": {
                             "type": "string",
index 2951d772f852f5921d15b8592385cea2d04ca3c8..5aeeadd12c6ee8ce187d7629653e8464f16c3415 100644 (file)
@@ -19,7 +19,7 @@
 
 use crate::jsonbuilder::{JsonBuilder, JsonError};
 
-use super::parser::{MediaDescription, SdpMessage};
+use super::parser::{MediaDescription, SdpMessage, TimeDescription};
 
 pub fn sdp_log(msg: &SdpMessage, js: &mut JsonBuilder) -> Result<(), JsonError> {
     js.open_object("sdp")?;
@@ -45,10 +45,7 @@ pub fn sdp_log(msg: &SdpMessage, js: &mut JsonBuilder) -> Result<(), JsonError>
     if let Some(bws) = &msg.bandwidths {
         log_bandwidth(bws, js)?;
     }
-    js.set_string("time", &msg.time)?;
-    if let Some(repeat_time) = &msg.repeat_time {
-        js.set_string("repeat_time", repeat_time)?;
-    }
+    log_time_description(&msg.time_description, js)?;
     if let Some(tz) = &msg.time_zone {
         js.set_string("timezone", tz)?;
     }
@@ -65,6 +62,22 @@ pub fn sdp_log(msg: &SdpMessage, js: &mut JsonBuilder) -> Result<(), JsonError>
     Ok(())
 }
 
+fn log_time_description(
+    time: &Vec<TimeDescription>, js: &mut JsonBuilder,
+) -> Result<(), JsonError> {
+    js.open_array("time_descriptions")?;
+    for t in time {
+        js.start_object()?;
+        js.set_string("time", &t.time)?;
+        if let Some(repeat_time) = &t.repeat_time {
+            js.set_string("repeat_time", repeat_time)?;
+        }
+        js.close()?;
+    }
+    js.close()?;
+    Ok(())
+}
+
 fn log_media_description(
     media: &Vec<MediaDescription>, js: &mut JsonBuilder,
 ) -> Result<(), JsonError> {
index 2f2baed9fc3d4f8662c4dfe9ab53bc879d7e9802..3ab9d932ca9f3e2039e6c9da9a9b808f383fe4b0 100644 (file)
@@ -48,8 +48,7 @@ pub struct SdpMessage {
     pub phone_number: Option<String>,
     pub connection_data: Option<String>,
     pub bandwidths: Option<Vec<String>>,
-    pub time: String,
-    pub repeat_time: Option<String>,
+    pub time_description: Vec<TimeDescription>,
     pub time_zone: Option<String>,
     pub encryption_key: Option<String>,
     pub attributes: Option<Vec<String>>,
@@ -66,6 +65,12 @@ pub struct MediaDescription {
     pub attributes: Option<Vec<String>>,
 }
 
+#[derive(Debug)]
+pub struct TimeDescription {
+    pub time: String,
+    pub repeat_time: Option<String>,
+}
+
 // token-char = %x21 / %x23-27 / %x2A-2B / %x2D-2E / %x30-39 / %x41-5A / %x5E-7E
 #[inline]
 fn is_token_char(b: u8) -> bool {
@@ -149,8 +154,7 @@ pub fn sdp_parse_message(i: &[u8]) -> IResult<&[u8], SdpMessage> {
     let (i, phone_number) = opt(parse_phone_number)(i)?;
     let (i, connection_data) = opt(parse_connection_data)(i)?;
     let (i, bandwidths) = opt(parse_bandwidth)(i)?;
-    let (i, time) = parse_time(i)?;
-    let (i, repeat_time) = opt(parse_repeat_times)(i)?;
+    let (i, time_description) = many1(parse_time_description)(i)?;
     let (i, time_zone) = opt(parse_time_zone)(i)?;
     let (i, encryption_key) = opt(parse_encryption_key)(i)?;
     let (i, attributes) = opt(parse_attributes)(i)?;
@@ -167,8 +171,7 @@ pub fn sdp_parse_message(i: &[u8]) -> IResult<&[u8], SdpMessage> {
             phone_number,
             connection_data,
             bandwidths,
-            time,
-            repeat_time,
+            time_description,
             time_zone,
             encryption_key,
             attributes,
@@ -309,6 +312,12 @@ fn parse_bandwidth(i: &[u8]) -> IResult<&[u8], Vec<String>> {
     Ok((i, vec))
 }
 
+fn parse_time_description(i: &[u8]) -> IResult<&[u8], TimeDescription> {
+    let (i, time) = parse_time(i)?;
+    let (i, repeat_time) = opt(parse_repeat_times)(i)?;
+    Ok((i, TimeDescription { time, repeat_time }))
+}
+
 fn parse_time(i: &[u8]) -> IResult<&[u8], String> {
     let (i, (start_time, _, stop_time)) = preceded(
         tag("t="),