From 5ed2af178af8f4291d1567909b59ebe85e2b4af7 Mon Sep 17 00:00:00 2001 From: James Laird Date: Sun, 25 Aug 2013 22:25:00 +1000 Subject: [PATCH] rtsp: send responses as single packets Under some circumstances, RTSP responses would be split into multiple packets. This causes Airfoil to barf, as it interprets the end of the packet as the end of the response. Since TCP_CORK is not portable, this fix buffers the packet on the stack before using a single write. This fixes issue #213. --- rtsp.c | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/rtsp.c b/rtsp.c index c6d64506..ef79defb 100644 --- a/rtsp.c +++ b/rtsp.c @@ -331,22 +331,32 @@ shutdown: } static void msg_write_response(int fd, rtsp_message *resp) { - char rbuf[30]; - int nrbuf; - nrbuf = snprintf(rbuf, sizeof(rbuf), - "RTSP/1.0 %d %s\r\n", resp->respcode, - resp->respcode==200 ? "OK" : "Error"); - write(fd, rbuf, nrbuf); - debug(1, "sending response: %s", rbuf); - int i; + char pkt[1024]; + int pktfree = sizeof(pkt); + char *p = pkt; + int i, n; + + n = snprintf(p, pktfree, + "RTSP/1.0 %d %s\r\n", resp->respcode, + resp->respcode==200 ? "OK" : "Error"); + debug(1, "sending response: %s", pkt); + pktfree -= n; + p += n; + for (i=0; inheaders; i++) { debug(2, " %s: %s\n", resp->name[i], resp->value[i]); - write(fd, resp->name[i], strlen(resp->name[i])); - write(fd, ": ", 2); - write(fd, resp->value[i], strlen(resp->value[i])); - write(fd, "\r\n", 2); + n = snprintf(p, pktfree, "%s: %s\r\n", resp->name[i], resp->value[i]); + pktfree -= n; + p += n; + if (pktfree <= 0) + die("Attempted to write overlong RTSP packet"); } - write(fd, "\r\n", 2); + + if (pktfree < 3) + die("Attempted to write overlong RTSP packet"); + + strcpy(p, "\r\n"); + write(fd, pkt, p-pkt+2); } static void handle_options(rtsp_conn_info *conn,