|
1 | 1 | /* |
2 | | - * TLS/SSL Protocol |
| 2 | + * TLS/DTLS/SSL Protocol |
3 | 3 | * Copyright (c) 2011 Martin Storsjo |
| 4 | + * Copyright (c) 2025 Jack Lau |
4 | 5 | * |
5 | 6 | * This file is part of FFmpeg. |
6 | 7 | * |
|
20 | 21 | */ |
21 | 22 |
|
22 | 23 | #include "avformat.h" |
| 24 | +#include "internal.h" |
23 | 25 | #include "network.h" |
24 | 26 | #include "os_support.h" |
25 | 27 | #include "url.h" |
@@ -93,7 +95,7 @@ int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AV |
93 | 95 | c->listen = 1; |
94 | 96 | } |
95 | 97 |
|
96 | | - ff_url_join(buf, sizeof(buf), "tcp", NULL, c->underlying_host, port, "%s", p); |
| 98 | + ff_url_join(buf, sizeof(buf), c->is_dtls ? "udp" : "tcp", NULL, c->underlying_host, port, "%s", p); |
97 | 99 |
|
98 | 100 | hints.ai_flags = AI_NUMERICHOST; |
99 | 101 | if (!getaddrinfo(c->underlying_host, NULL, &hints, &ai)) { |
@@ -124,7 +126,65 @@ int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AV |
124 | 126 | } |
125 | 127 |
|
126 | 128 | freeenv_utf8(env_http_proxy); |
127 | | - return ffurl_open_whitelist(&c->tcp, buf, AVIO_FLAG_READ_WRITE, |
128 | | - &parent->interrupt_callback, options, |
129 | | - parent->protocol_whitelist, parent->protocol_blacklist, parent); |
| 129 | + if (c->is_dtls) { |
| 130 | + av_dict_set_int(options, "connect", 1, 0); |
| 131 | + av_dict_set_int(options, "fifo_size", 0, 0); |
| 132 | + /* Set the max packet size to the buffer size. */ |
| 133 | + av_dict_set_int(options, "pkt_size", c->mtu, 0); |
| 134 | + } |
| 135 | + ret = ffurl_open_whitelist(c->is_dtls ? &c->udp : &c->tcp, buf, AVIO_FLAG_READ_WRITE, |
| 136 | + &parent->interrupt_callback, options, |
| 137 | + parent->protocol_whitelist, parent->protocol_blacklist, parent); |
| 138 | + if (c->is_dtls) { |
| 139 | + if (ret < 0) { |
| 140 | + av_log(c, AV_LOG_ERROR, "WHIP: Failed to connect udp://%s:%d\n", c->underlying_host, port); |
| 141 | + return ret; |
| 142 | + } |
| 143 | + /* Make the socket non-blocking, set to READ and WRITE mode after connected */ |
| 144 | + ff_socket_nonblock(ffurl_get_file_handle(c->udp), 1); |
| 145 | + c->udp->flags |= AVIO_FLAG_READ | AVIO_FLAG_NONBLOCK; |
| 146 | + } |
| 147 | + return ret; |
| 148 | +} |
| 149 | + |
| 150 | +/** |
| 151 | + * Read all data from the given URL url and store it in the given buffer bp. |
| 152 | + */ |
| 153 | +int ff_url_read_all(const char *url, AVBPrint *bp) |
| 154 | +{ |
| 155 | + int ret = 0; |
| 156 | + AVDictionary *opts = NULL; |
| 157 | + URLContext *uc = NULL; |
| 158 | + char buf[MAX_URL_SIZE]; |
| 159 | + |
| 160 | + ret = ffurl_open_whitelist(&uc, url, AVIO_FLAG_READ, NULL, &opts, NULL, NULL, NULL); |
| 161 | + if (ret < 0) { |
| 162 | + av_log(NULL, AV_LOG_ERROR, "TLS: Failed to open url %s\n", url); |
| 163 | + goto end; |
| 164 | + } |
| 165 | + |
| 166 | + while (1) { |
| 167 | + ret = ffurl_read(uc, buf, sizeof(buf)); |
| 168 | + if (ret == AVERROR_EOF) { |
| 169 | + /* Reset the error because we read all response as answer util EOF. */ |
| 170 | + ret = 0; |
| 171 | + break; |
| 172 | + } |
| 173 | + if (ret <= 0) { |
| 174 | + av_log(NULL, AV_LOG_ERROR, "TLS: Failed to read from url=%s, key is %s\n", url, bp->str); |
| 175 | + goto end; |
| 176 | + } |
| 177 | + |
| 178 | + av_bprintf(bp, "%.*s", ret, buf); |
| 179 | + if (!av_bprint_is_complete(bp)) { |
| 180 | + av_log(NULL, AV_LOG_ERROR, "TLS: Exceed max size %.*s, %s\n", ret, buf, bp->str); |
| 181 | + ret = AVERROR(EIO); |
| 182 | + goto end; |
| 183 | + } |
| 184 | + } |
| 185 | + |
| 186 | +end: |
| 187 | + ffurl_closep(&uc); |
| 188 | + av_dict_free(&opts); |
| 189 | + return ret; |
130 | 190 | } |
0 commit comments