From: Stefan Eissing Date: Tue, 6 May 2025 08:44:27 +0000 (+0200) Subject: rtsp: move easy handle/connection protoocol structs into meta data X-Git-Tag: curl-8_14_0~153 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=2e49965126f190003c8556cadcf8ed40bca25d11;p=thirdparty%2Fcurl.git rtsp: move easy handle/connection protoocol structs into meta data Remove the connectdata proto and data->req.p member for rtsp and manage the structs as meta data at easy handle/connection. Closes #17254 --- diff --git a/lib/request.h b/lib/request.h index cdb2371335..9e3fc24692 100644 --- a/lib/request.h +++ b/lib/request.h @@ -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; diff --git a/lib/rtsp.c b/lib/rtsp.c index 1f7929cc52..9437539c8d 100644 --- a/lib/rtsp.c +++ b/lib/rtsp.c @@ -46,6 +46,36 @@ #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); diff --git a/lib/rtsp.h b/lib/rtsp.h index 2506ea9cb8..59f20a9f16 100644 --- a/lib/rtsp.h +++ b/lib/rtsp.h @@ -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 */ diff --git a/lib/urldata.h b/lib/urldata.h index 2b6100d173..c524cc122b 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -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