]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
rtsp: move easy handle/connection protoocol structs into meta data
authorStefan Eissing <stefan@eissing.org>
Tue, 6 May 2025 08:44:27 +0000 (10:44 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 6 May 2025 15:13:24 +0000 (17:13 +0200)
Remove the connectdata proto and data->req.p member for rtsp and manage
the structs as meta data at easy handle/connection.

Closes #17254

lib/request.h
lib/rtsp.c
lib/rtsp.h
lib/urldata.h

index cdb2371335bb0ed4809c995002fe8bd211332ea0..9e3fc24692caf6264d9b0f32ab430a6e00858df3 100644 (file)
@@ -105,7 +105,6 @@ struct SingleRequest {
     struct FILEPROTO *file;
     struct IMAP *imap;
     struct ldapreqinfo *ldap;
-    struct RTSP *rtsp;
     struct SMTP *smtp;
     struct SSHPROTO *ssh;
     struct TELNET *telnet;
index 1f7929cc526abe315c4ad9ce234fbd4666581a48..9437539c8df657190d1861e900aa9529ac9d678b 100644 (file)
 #include "curl_memory.h"
 #include "memdebug.h"
 
+
+/* meta key for storing protocol meta at easy handle */
+#define CURL_META_RTSP_EASY   "meta:proto:rtsp:easy"
+/* meta key for storing protocol meta at connection */
+#define CURL_META_RTSP_CONN   "meta:proto:rtsp:conn"
+
+typedef enum {
+  RTP_PARSE_SKIP,
+  RTP_PARSE_CHANNEL,
+  RTP_PARSE_LEN,
+  RTP_PARSE_DATA
+} rtp_parse_st;
+
+/* RTSP Connection data
+ * Currently, only used for tracking incomplete RTP data reads */
+struct rtsp_conn {
+  struct dynbuf buf;
+  int rtp_channel;
+  size_t rtp_len;
+  rtp_parse_st state;
+  BIT(in_header);
+};
+
+/* RTSP transfer data */
+struct RTSP {
+  long CSeq_sent; /* CSeq of this request */
+  long CSeq_recv; /* CSeq received */
+};
+
+
 #define RTP_PKT_LENGTH(p) ((((unsigned int)((unsigned char)((p)[2]))) << 8) | \
                             ((unsigned int)((unsigned char)((p)[3]))))
 
@@ -53,8 +83,6 @@
 static CURLcode rtsp_do(struct Curl_easy *data, bool *done);
 static CURLcode rtsp_done(struct Curl_easy *data, CURLcode, bool premature);
 static CURLcode rtsp_connect(struct Curl_easy *data, bool *done);
-static CURLcode rtsp_disconnect(struct Curl_easy *data,
-                                struct connectdata *conn, bool dead);
 static int rtsp_getsock_do(struct Curl_easy *data,
                            struct connectdata *conn, curl_socket_t *socks);
 
@@ -113,7 +141,7 @@ const struct Curl_handler Curl_handler_rtsp = {
   rtsp_getsock_do,                      /* doing_getsock */
   ZERO_NULL,                            /* domore_getsock */
   ZERO_NULL,                            /* perform_getsock */
-  rtsp_disconnect,                      /* disconnect */
+  ZERO_NULL,                            /* disconnect */
   rtsp_rtp_write_resp,                  /* write_resp */
   ZERO_NULL,                            /* write_resp_hd */
   rtsp_conncheck,                       /* connection_check */
@@ -127,20 +155,39 @@ const struct Curl_handler Curl_handler_rtsp = {
 
 #define MAX_RTP_BUFFERSIZE 1000000 /* arbitrary */
 
+static void rtsp_easy_dtor(void *key, size_t klen, void *entry)
+{
+  struct RTSP *rtsp = entry;
+  (void)key;
+  (void)klen;
+  free(rtsp);
+}
+
+static void rtsp_conn_dtor(void *key, size_t klen, void *entry)
+{
+  struct rtsp_conn *rtspc = entry;
+  (void)key;
+  (void)klen;
+  Curl_dyn_free(&rtspc->buf);
+  free(rtspc);
+}
+
 static CURLcode rtsp_setup_connection(struct Curl_easy *data,
                                       struct connectdata *conn)
 {
-  struct rtsp_conn *rtspc = &conn->proto.rtspc;
+  struct rtsp_conn *rtspc;
   struct RTSP *rtsp;
-  (void)conn;
 
-  if(!rtspc->initialised) {
-    Curl_dyn_init(&rtspc->buf, MAX_RTP_BUFFERSIZE);
-    rtspc->initialised = TRUE;
-  }
+  rtspc = calloc(1, sizeof(*rtspc));
+  if(!rtspc)
+    return CURLE_OUT_OF_MEMORY;
+  Curl_dyn_init(&rtspc->buf, MAX_RTP_BUFFERSIZE);
+  if(Curl_conn_meta_set(conn, CURL_META_RTSP_CONN, rtspc, rtsp_conn_dtor))
+    return CURLE_OUT_OF_MEMORY;
 
-  data->req.p.rtsp = rtsp = calloc(1, sizeof(struct RTSP));
-  if(!rtsp)
+  rtsp = calloc(1, sizeof(struct RTSP));
+  if(!rtsp ||
+     Curl_meta_set(data, CURL_META_RTSP_EASY, rtsp, rtsp_easy_dtor))
     return CURLE_OUT_OF_MEMORY;
 
   return CURLE_OK;
@@ -169,8 +216,13 @@ static unsigned int rtsp_conncheck(struct Curl_easy *data,
 
 static CURLcode rtsp_connect(struct Curl_easy *data, bool *done)
 {
+  struct rtsp_conn *rtspc =
+    Curl_conn_meta_get(data->conn, CURL_META_RTSP_CONN);
   CURLcode httpStatus;
 
+  if(!rtspc)
+    return CURLE_FAILED_INIT;
+
   httpStatus = Curl_http_connect(data, done);
 
   /* Initialize the CSeq if not already done */
@@ -179,31 +231,22 @@ static CURLcode rtsp_connect(struct Curl_easy *data, bool *done)
   if(data->state.rtsp_next_server_CSeq == 0)
     data->state.rtsp_next_server_CSeq = 1;
 
-  data->conn->proto.rtspc.rtp_channel = -1;
+  rtspc->rtp_channel = -1;
 
   return httpStatus;
 }
 
-static CURLcode rtsp_disconnect(struct Curl_easy *data,
-                                struct connectdata *conn, bool dead)
-{
-  struct rtsp_conn *rtspc = &conn->proto.rtspc;
-  (void) dead;
-  (void) data;
-  if(rtspc->initialised) {
-    Curl_dyn_free(&conn->proto.rtspc.buf);
-    rtspc->initialised = FALSE;
-  }
-  return CURLE_OK;
-}
-
-
 static CURLcode rtsp_done(struct Curl_easy *data,
                           CURLcode status, bool premature)
 {
-  struct RTSP *rtsp = data->req.p.rtsp;
+  struct rtsp_conn *rtspc =
+    Curl_conn_meta_get(data->conn, CURL_META_RTSP_CONN);
+  struct RTSP *rtsp = Curl_meta_get(data, CURL_META_RTSP_EASY);
   CURLcode httpStatus;
 
+  if(!rtspc || !rtsp)
+    return CURLE_FAILED_INIT;
+
   /* Bypass HTTP empty-reply checks on receive */
   if(data->set.rtspreq == RTSPREQ_RECEIVE)
     premature = TRUE;
@@ -220,8 +263,7 @@ static CURLcode rtsp_done(struct Curl_easy *data,
             CSeq_sent, CSeq_recv);
       return CURLE_RTSP_CSEQ_ERROR;
     }
-    if(data->set.rtspreq == RTSPREQ_RECEIVE &&
-       (data->conn->proto.rtspc.rtp_channel == -1)) {
+    if(data->set.rtspreq == RTSPREQ_RECEIVE && (rtspc->rtp_channel == -1)) {
       infof(data, "Got an RTP Receive with a CSeq of %ld", CSeq_recv);
     }
     if(data->set.rtspreq == RTSPREQ_RECEIVE &&
@@ -239,7 +281,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
   struct connectdata *conn = data->conn;
   CURLcode result = CURLE_OK;
   Curl_RtspReq rtspreq = data->set.rtspreq;
-  struct RTSP *rtsp = data->req.p.rtsp;
+  struct RTSP *rtsp = Curl_meta_get(data, CURL_META_RTSP_EASY);
   struct dynbuf req_buffer;
   unsigned char httpversion = 11; /* RTSP is close to HTTP/1.1, sort of... */
 
@@ -256,6 +298,9 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
   const char *p_userpwd = NULL;
 
   *done = TRUE;
+  if(!rtsp)
+    return CURLE_FAILED_INIT;
+
   /* Initialize a dynamic send buffer */
   Curl_dyn_init(&req_buffer, DYN_RTSP_REQ_HEADER);
 
@@ -621,10 +666,10 @@ out:
  * write any BODY bytes missing to the client, ignore the rest.
  */
 static CURLcode rtp_write_body_junk(struct Curl_easy *data,
+                                    struct rtsp_conn *rtspc,
                                     const char *buf,
                                     size_t blen)
 {
-  struct rtsp_conn *rtspc = &(data->conn->proto.rtspc);
   curl_off_t body_remain;
   bool in_body;
 
@@ -642,11 +687,11 @@ static CURLcode rtp_write_body_junk(struct Curl_easy *data,
 }
 
 static CURLcode rtsp_filter_rtp(struct Curl_easy *data,
-                                     const char *buf,
-                                     size_t blen,
-                                     size_t *pconsumed)
+                                struct rtsp_conn *rtspc,
+                                const char *buf,
+                                size_t blen,
+                                size_t *pconsumed)
 {
-  struct rtsp_conn *rtspc = &(data->conn->proto.rtspc);
   CURLcode result = CURLE_OK;
   size_t skip_len = 0;
 
@@ -683,7 +728,7 @@ static CURLcode rtsp_filter_rtp(struct Curl_easy *data,
         /* possible start of an RTP message, buffer */
         if(skip_len) {
           /* end of junk/BODY bytes, flush */
-          result = rtp_write_body_junk(data, buf - skip_len, skip_len);
+          result = rtp_write_body_junk(data, rtspc, buf - skip_len, skip_len);
           skip_len = 0;
           if(result)
             goto out;
@@ -714,7 +759,8 @@ static CURLcode rtsp_filter_rtp(struct Curl_easy *data,
           /* We did not consume the initial '$' in our buffer, but had
            * it from an earlier call. We cannot un-consume it and have
            * to write it directly as BODY data */
-          result = rtp_write_body_junk(data, Curl_dyn_ptr(&rtspc->buf), 1);
+          result = rtp_write_body_junk(data, rtspc,
+                                       Curl_dyn_ptr(&rtspc->buf), 1);
           if(result)
             goto out;
         }
@@ -799,7 +845,7 @@ static CURLcode rtsp_filter_rtp(struct Curl_easy *data,
   }
 out:
   if(!result && skip_len)
-    result = rtp_write_body_junk(data, buf - skip_len, skip_len);
+    result = rtp_write_body_junk(data, rtspc, buf - skip_len, skip_len);
   return result;
 }
 
@@ -808,10 +854,14 @@ static CURLcode rtsp_rtp_write_resp(struct Curl_easy *data,
                                     size_t blen,
                                     bool is_eos)
 {
-  struct rtsp_conn *rtspc = &(data->conn->proto.rtspc);
+  struct rtsp_conn *rtspc =
+    Curl_conn_meta_get(data->conn, CURL_META_RTSP_CONN);
   CURLcode result = CURLE_OK;
   size_t consumed = 0;
 
+  if(!rtspc)
+    return CURLE_FAILED_INIT;
+
   if(!data->req.header)
     rtspc->in_header = FALSE;
   if(!blen) {
@@ -823,7 +873,7 @@ static CURLcode rtsp_rtp_write_resp(struct Curl_easy *data,
 
   /* If header parsing is not ongoing, extract RTP messages */
   if(!rtspc->in_header) {
-    result = rtsp_filter_rtp(data, buf, blen, &consumed);
+    result = rtsp_filter_rtp(data, rtspc, buf, blen, &consumed);
     if(result)
       goto out;
     buf += consumed;
@@ -855,7 +905,7 @@ static CURLcode rtsp_rtp_write_resp(struct Curl_easy *data,
         data->req.size = 0;
         data->req.download_done = TRUE;
       }
-      result = rtsp_filter_rtp(data, buf, blen, &consumed);
+      result = rtsp_filter_rtp(data, rtspc, buf, blen, &consumed);
       if(result)
         goto out;
       blen -= consumed;
@@ -933,8 +983,10 @@ CURLcode Curl_rtsp_parseheader(struct Curl_easy *data, const char *header)
 {
   if(checkprefix("CSeq:", header)) {
     curl_off_t CSeq = 0;
-    struct RTSP *rtsp = data->req.p.rtsp;
+    struct RTSP *rtsp = Curl_meta_get(data, CURL_META_RTSP_EASY);
     const char *p = &header[5];
+    if(!rtsp)
+      return CURLE_FAILED_INIT;
     Curl_str_passblanks(&p);
     if(Curl_str_number(&p, &CSeq, LONG_MAX)) {
       failf(data, "Unable to read the CSeq header: [%s]", header);
index 2506ea9cb849b0e4e172c541f96760c526d74f89..59f20a9f1672923ccb1c98a997aaf35a6e0b3b94 100644 (file)
@@ -36,33 +36,4 @@ CURLcode Curl_rtsp_parseheader(struct Curl_easy *data, const char *header);
 
 #endif /* CURL_DISABLE_RTSP */
 
-typedef enum {
-  RTP_PARSE_SKIP,
-  RTP_PARSE_CHANNEL,
-  RTP_PARSE_LEN,
-  RTP_PARSE_DATA
-} rtp_parse_st;
-/*
- * RTSP Connection data
- *
- * Currently, only used for tracking incomplete RTP data reads
- */
-struct rtsp_conn {
-  struct dynbuf buf;
-  int rtp_channel;
-  size_t rtp_len;
-  rtp_parse_st state;
-  BIT(in_header);
-  BIT(initialised);
-};
-
-/****************************************************************************
- * RTSP unique setup
- ***************************************************************************/
-struct RTSP {
-  long CSeq_sent; /* CSeq of this request */
-  long CSeq_recv; /* CSeq received */
-};
-
-
 #endif /* HEADER_CURL_RTSP_H */
index 2b6100d173b30cc710e406800f4e32392e780973..c524cc122b0693b98819b5be47b216d082e70ab4 100644 (file)
@@ -872,9 +872,6 @@ struct connectdata {
 #ifndef CURL_DISABLE_SMTP
     struct smtp_conn smtpc;
 #endif
-#ifndef CURL_DISABLE_RTSP
-    struct rtsp_conn rtspc;
-#endif
 #ifdef USE_LIBRTMP
     void *rtmp;
 #endif