rtsp: convert mallocs to dynbuf for RTP buffering

Closes #10786
This commit is contained in:
Daniel Stenberg 2023-04-04 14:44:25 +02:00
parent 808cb31756
commit 4399a532e9
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
2 changed files with 20 additions and 43 deletions

View File

@ -119,6 +119,7 @@ const struct Curl_handler Curl_handler_rtsp = {
PROTOPT_NONE /* flags */ PROTOPT_NONE /* flags */
}; };
#define MAX_RTP_BUFFERSIZE 1000000 /* arbitrary */
static CURLcode rtsp_setup_connection(struct Curl_easy *data, static CURLcode rtsp_setup_connection(struct Curl_easy *data,
struct connectdata *conn) struct connectdata *conn)
@ -130,6 +131,7 @@ static CURLcode rtsp_setup_connection(struct Curl_easy *data,
if(!rtsp) if(!rtsp)
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
Curl_dyn_init(&conn->proto.rtspc.buf, MAX_RTP_BUFFERSIZE);
return CURLE_OK; return CURLE_OK;
} }
@ -176,7 +178,7 @@ static CURLcode rtsp_disconnect(struct Curl_easy *data,
{ {
(void) dead; (void) dead;
(void) data; (void) data;
Curl_safefree(conn->proto.rtspc.rtp_buf); Curl_dyn_free(&conn->proto.rtspc.buf);
return CURLE_OK; return CURLE_OK;
} }
@ -204,7 +206,7 @@ static CURLcode rtsp_done(struct Curl_easy *data,
return CURLE_RTSP_CSEQ_ERROR; return CURLE_RTSP_CSEQ_ERROR;
} }
if(data->set.rtspreq == RTSPREQ_RECEIVE && if(data->set.rtspreq == RTSPREQ_RECEIVE &&
(data->conn->proto.rtspc.rtp_channel == -1)) { (data->conn->proto.rtspc.rtp_channel == -1)) {
infof(data, "Got an RTP Receive with a CSeq of %ld", CSeq_recv); infof(data, "Got an RTP Receive with a CSeq of %ld", CSeq_recv);
} }
} }
@ -598,25 +600,16 @@ static CURLcode rtsp_rtp_readwrite(struct Curl_easy *data,
char *rtp; /* moving pointer to rtp data */ char *rtp; /* moving pointer to rtp data */
ssize_t rtp_dataleft; /* how much data left to parse in this round */ ssize_t rtp_dataleft; /* how much data left to parse in this round */
char *scratch;
CURLcode result; CURLcode result;
bool interleaved = false; bool interleaved = false;
size_t skip_size = 0; size_t skip_size = 0;
if(rtspc->rtp_buf) { if(Curl_dyn_len(&rtspc->buf)) {
/* There was some leftover data the last time. Merge buffers */ /* There was some leftover data the last time. Append new buffers */
char *newptr = Curl_saferealloc(rtspc->rtp_buf, if(Curl_dyn_addn(&rtspc->buf, k->str, *nread))
rtspc->rtp_bufsize + *nread);
if(!newptr) {
rtspc->rtp_buf = NULL;
rtspc->rtp_bufsize = 0;
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
} rtp = Curl_dyn_ptr(&rtspc->buf);
rtspc->rtp_buf = newptr; rtp_dataleft = Curl_dyn_len(&rtspc->buf);
memcpy(rtspc->rtp_buf + rtspc->rtp_bufsize, k->str, *nread);
rtspc->rtp_bufsize += *nread;
rtp = rtspc->rtp_buf;
rtp_dataleft = rtspc->rtp_bufsize;
} }
else { else {
/* Just parse the request buffer directly */ /* Just parse the request buffer directly */
@ -667,9 +660,6 @@ static CURLcode rtsp_rtp_readwrite(struct Curl_easy *data,
result = rtp_client_write(data, &rtp[0], rtp_length + 4); result = rtp_client_write(data, &rtp[0], rtp_length + 4);
if(result) { if(result) {
*readmore = FALSE; *readmore = FALSE;
Curl_safefree(rtspc->rtp_buf);
rtspc->rtp_buf = NULL;
rtspc->rtp_bufsize = 0;
return result; return result;
} }
@ -716,20 +706,18 @@ static CURLcode rtsp_rtp_readwrite(struct Curl_easy *data,
if(rtp_dataleft && rtp[0] == '$') { if(rtp_dataleft && rtp[0] == '$') {
DEBUGF(infof(data, "RTP Rewinding %zd %s", rtp_dataleft, DEBUGF(infof(data, "RTP Rewinding %zd %s", rtp_dataleft,
*readmore ? "(READMORE)" : "")); *readmore ? "(READMORE)" : ""));
/* Store the incomplete RTP packet for a "rewind" */ /* Store the incomplete RTP packet for a "rewind" */
scratch = malloc(rtp_dataleft); if(!Curl_dyn_len(&rtspc->buf)) {
if(!scratch) { /* nothing was stored, add this data */
Curl_safefree(rtspc->rtp_buf); if(Curl_dyn_addn(&rtspc->buf, rtp, rtp_dataleft))
rtspc->rtp_buf = NULL; return CURLE_OUT_OF_MEMORY;
rtspc->rtp_bufsize = 0; }
return CURLE_OUT_OF_MEMORY; else {
/* keep the remainder */
Curl_dyn_tail(&rtspc->buf, rtp_dataleft);
} }
memcpy(scratch, rtp, rtp_dataleft);
Curl_safefree(rtspc->rtp_buf);
rtspc->rtp_buf = scratch;
rtspc->rtp_bufsize = rtp_dataleft;
/* As far as the transfer is concerned, this data is consumed */ /* As far as the transfer is concerned, this data is consumed */
*nread = 0; *nread = 0;
@ -738,20 +726,10 @@ static CURLcode rtsp_rtp_readwrite(struct Curl_easy *data,
/* Fix up k->str to point just after the last RTP packet */ /* Fix up k->str to point just after the last RTP packet */
k->str += *nread - rtp_dataleft; k->str += *nread - rtp_dataleft;
/* either all of the data has been read or...
* rtp now points at the next byte to parse
*/
if(rtp_dataleft > 0)
DEBUGASSERT(k->str[0] == rtp[0]);
DEBUGASSERT(rtp_dataleft <= *nread); /* sanity check */
*nread = rtp_dataleft; *nread = rtp_dataleft;
/* If we get here, we have finished with the leftover/merge buffer */ /* If we get here, we have finished with the leftover/merge buffer */
Curl_safefree(rtspc->rtp_buf); Curl_dyn_free(&rtspc->buf);
rtspc->rtp_buf = NULL;
rtspc->rtp_bufsize = 0;
return CURLE_OK; return CURLE_OK;
} }

View File

@ -45,8 +45,7 @@ CURLcode Curl_rtsp_parseheader(struct Curl_easy *data, char *header);
* Currently, only used for tracking incomplete RTP data reads * Currently, only used for tracking incomplete RTP data reads
*/ */
struct rtsp_conn { struct rtsp_conn {
char *rtp_buf; struct dynbuf buf;
ssize_t rtp_bufsize;
int rtp_channel; int rtp_channel;
}; };