lib571.c (5742B)
1 /*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 9 * 10 * This software is licensed as described in the file COPYING, which 11 * you should have received as part of this distribution. The terms 12 * are also available at https://curl.se/docs/copyright.html. 13 * 14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 15 * copies of the Software, and permit persons to whom the Software is 16 * furnished to do so, under the terms of the COPYING file. 17 * 18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19 * KIND, either express or implied. 20 * 21 * SPDX-License-Identifier: curl 22 * 23 ***************************************************************************/ 24 #include "first.h" 25 26 #ifdef HAVE_NETINET_IN_H 27 #include <netinet/in.h> 28 #endif 29 #ifdef HAVE_NETDB_H 30 #include <netdb.h> 31 #endif 32 #ifdef HAVE_ARPA_INET_H 33 #include <arpa/inet.h> 34 #endif 35 36 #include "testutil.h" 37 #include "memdebug.h" 38 39 #define RTP_PKT_CHANNEL(p) ((int)((unsigned char)((p)[1]))) 40 41 #define RTP_PKT_LENGTH(p) ((((int)((unsigned char)((p)[2]))) << 8) | \ 42 ((int)((unsigned char)((p)[3])))) 43 44 #define RTP_DATA_SIZE 12 45 46 static int rtp_packet_count = 0; 47 48 static size_t rtp_write(char *ptr, size_t size, size_t nmemb, void *stream) 49 { 50 static const char *RTP_DATA = "$_1234\n\0Rsdf"; 51 52 char *data = (char *)ptr; 53 int channel = RTP_PKT_CHANNEL(data); 54 int message_size; 55 int coded_size = RTP_PKT_LENGTH(data); 56 size_t failure = (size && nmemb) ? 0 : 1; 57 int i; 58 (void)stream; 59 60 message_size = curlx_uztosi(size * nmemb) - 4; 61 62 curl_mprintf("RTP: message size %d, channel %d\n", message_size, channel); 63 if(message_size != coded_size) { 64 curl_mprintf("RTP embedded size (%d) does not match " 65 "the write size (%d).\n", 66 coded_size, message_size); 67 return failure; 68 } 69 70 data += 4; 71 for(i = 0; i < message_size; i += RTP_DATA_SIZE) { 72 if(message_size - i > RTP_DATA_SIZE) { 73 if(memcmp(RTP_DATA, data + i, RTP_DATA_SIZE) != 0) { 74 curl_mprintf("RTP PAYLOAD CORRUPTED [%s]\n", data + i); 75 /* return failure; */ 76 } 77 } 78 else { 79 if(memcmp(RTP_DATA, data + i, message_size - i) != 0) { 80 curl_mprintf("RTP PAYLOAD END CORRUPTED (%d), [%s]\n", 81 message_size - i, data + i); 82 /* return failure; */ 83 } 84 } 85 } 86 87 rtp_packet_count++; 88 curl_mfprintf(stderr, "packet count is %d\n", rtp_packet_count); 89 90 return size * nmemb; 91 } 92 93 static CURLcode test_lib571(char *URL) 94 { 95 CURLcode res; 96 CURL *curl; 97 char *stream_uri = NULL; 98 int request = 1; 99 100 FILE *protofile = fopen(libtest_arg2, "wb"); 101 if(!protofile) { 102 curl_mfprintf(stderr, "Couldn't open the protocol dump file\n"); 103 return TEST_ERR_MAJOR_BAD; 104 } 105 106 if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { 107 curl_mfprintf(stderr, "curl_global_init() failed\n"); 108 fclose(protofile); 109 return TEST_ERR_MAJOR_BAD; 110 } 111 112 curl = curl_easy_init(); 113 if(!curl) { 114 curl_mfprintf(stderr, "curl_easy_init() failed\n"); 115 fclose(protofile); 116 curl_global_cleanup(); 117 return TEST_ERR_MAJOR_BAD; 118 } 119 test_setopt(curl, CURLOPT_URL, URL); 120 121 stream_uri = tutil_suburl(URL, request++); 122 if(!stream_uri) { 123 res = TEST_ERR_MAJOR_BAD; 124 goto test_cleanup; 125 } 126 test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri); 127 curl_free(stream_uri); 128 stream_uri = NULL; 129 130 test_setopt(curl, CURLOPT_INTERLEAVEFUNCTION, rtp_write); 131 test_setopt(curl, CURLOPT_TIMEOUT, 30L); 132 test_setopt(curl, CURLOPT_VERBOSE, 1L); 133 test_setopt(curl, CURLOPT_WRITEDATA, protofile); 134 135 test_setopt(curl, CURLOPT_RTSP_TRANSPORT, "RTP/AVP/TCP;interleaved=0-1"); 136 test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_SETUP); 137 138 res = curl_easy_perform(curl); 139 if(res) 140 goto test_cleanup; 141 142 /* This PLAY starts the interleave */ 143 stream_uri = tutil_suburl(URL, request++); 144 if(!stream_uri) { 145 res = TEST_ERR_MAJOR_BAD; 146 goto test_cleanup; 147 } 148 test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri); 149 curl_free(stream_uri); 150 stream_uri = NULL; 151 test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_PLAY); 152 153 res = curl_easy_perform(curl); 154 if(res) 155 goto test_cleanup; 156 157 /* The DESCRIBE request will try to consume data after the Content */ 158 stream_uri = tutil_suburl(URL, request++); 159 if(!stream_uri) { 160 res = TEST_ERR_MAJOR_BAD; 161 goto test_cleanup; 162 } 163 test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri); 164 curl_free(stream_uri); 165 stream_uri = NULL; 166 test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_DESCRIBE); 167 168 res = curl_easy_perform(curl); 169 if(res) 170 goto test_cleanup; 171 172 stream_uri = tutil_suburl(URL, request++); 173 if(!stream_uri) { 174 res = TEST_ERR_MAJOR_BAD; 175 goto test_cleanup; 176 } 177 test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri); 178 curl_free(stream_uri); 179 stream_uri = NULL; 180 test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_PLAY); 181 182 res = curl_easy_perform(curl); 183 if(res) 184 goto test_cleanup; 185 186 curl_mfprintf(stderr, "PLAY COMPLETE\n"); 187 188 /* Use Receive to get the rest of the data */ 189 while(!res && rtp_packet_count < 19) { 190 curl_mfprintf(stderr, "LOOPY LOOP!\n"); 191 test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_RECEIVE); 192 res = curl_easy_perform(curl); 193 } 194 195 test_cleanup: 196 curl_free(stream_uri); 197 198 if(protofile) 199 fclose(protofile); 200 201 curl_easy_cleanup(curl); 202 curl_global_cleanup(); 203 204 return res; 205 }