From 1a6cbd16da7afa8312bc8f9e9419ea9db42f8bcf Mon Sep 17 00:00:00 2001 From: Maksym Sobolyev Date: Mon, 20 Apr 2015 18:53:07 -0700 Subject: [PATCH] Fix overflow bug in the RTP traffic generator, which uses 32-bit timestamp from the rtp header to track its progress. The problem here is we keep the session for some 6.2 days, that counter overflows and we go into infinite loop spewing packet at the max rate our sender threads can handle them, which is about 100Kpps on our reference hardware. We need to figure out why that session has managed to stay up for so long, but in any case moving to 64-bit counter would provide us wastly more time till overlow. The separate question is why session managed to stay active for so long, but we will probably address that in a separate changeset. --- src/rtp_server.c | 14 +++++++------- src/rtp_server.h | 2 +- src/rtpp_command.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/rtp_server.c b/src/rtp_server.c index 9279a66..3c09e3d 100644 --- a/src/rtp_server.c +++ b/src/rtp_server.c @@ -49,10 +49,11 @@ struct rtp_server { unsigned char *pload; int fd; int loop; + uint64_t dts; }; struct rtp_server * -rtp_server_new(const char *name, rtp_type_t codec, int loop) +rtp_server_new(const char *name, rtp_type_t codec, int loop, double dtime) { struct rtp_server *rp; int fd; @@ -71,7 +72,8 @@ rtp_server_new(const char *name, rtp_type_t codec, int loop) memset(rp, 0, sizeof(*rp)); - rp->btime = -1; + rp->btime = dtime; + rp->dts = 0; rp->fd = fd; rp->loop = (loop > 0) ? loop - 1 : loop; @@ -106,12 +108,8 @@ rtp_server_get(struct rtp_server *rp, double dtime, int *rval) int rlen, rticks, bytes_per_frame, ticks_per_frame, number_of_frames; int hlen; - if (rp->btime == -1) - rp->btime = dtime; - ts = ntohl(rp->rtp->ts); - - if (rp->btime + ((double)ts / RTPS_SRATE) > dtime) { + if (rp->btime + ((double)rp->dts / 1000.0) > dtime) { *rval = RTPS_LATER; return (NULL); } @@ -157,6 +155,7 @@ rtp_server_get(struct rtp_server *rp, double dtime, int *rval) rlen = bytes_per_frame * number_of_frames; rticks = ticks_per_frame * number_of_frames; + rp->dts += rticks; pkt = rtp_packet_alloc(); if (pkt == NULL) { @@ -180,6 +179,7 @@ rtp_server_get(struct rtp_server *rp, double dtime, int *rval) rp->rtp->m = 0; } + ts = ntohl(rp->rtp->ts); rp->rtp->ts = htonl(ts + (RTPS_SRATE * rticks / 1000)); rp->rtp->seq = htons(ntohs(rp->rtp->seq) + 1); diff --git a/src/rtp_server.h b/src/rtp_server.h index b12742b..7b5d1fb 100644 --- a/src/rtp_server.h +++ b/src/rtp_server.h @@ -47,7 +47,7 @@ struct rtp_server; struct rtpp_session; struct cfg; -struct rtp_server *rtp_server_new(const char *, rtp_type_t, int); +struct rtp_server *rtp_server_new(const char *, rtp_type_t, int, double); void rtp_server_free(struct rtp_server *); struct rtp_packet *rtp_server_get(struct rtp_server *, double, int *); void append_server(struct cfg *, struct rtpp_session *); diff --git a/src/rtpp_command.c b/src/rtpp_command.c index 60b1252..298da45 100644 --- a/src/rtpp_command.c +++ b/src/rtpp_command.c @@ -635,7 +635,7 @@ handle_play(struct cfg *cf, struct rtpp_session *spa, int idx, char *codecs, codecs = cp; if (*codecs != '\0') codecs++; - spa->rtps[idx] = rtp_server_new(pname, n, playcount); + spa->rtps[idx] = rtp_server_new(pname, n, playcount, cmd->dtime); if (spa->rtps[idx] == NULL) continue; cmd->csp->nplrs_created.cnt++; -- 2.12.2