|  |  | @@ -43,6 +43,9 @@ typedef struct TLSContext { | 
		
	
		
			
			|  |  |  | TLSShared tls_shared; | 
		
	
		
			
			|  |  |  | SSL_CTX *ctx; | 
		
	
		
			
			|  |  |  | SSL *ssl; | 
		
	
		
			
			|  |  |  | #if OPENSSL_VERSION_NUMBER >= 0x1010000fL | 
		
	
		
			
			|  |  |  | BIO_METHOD* url_bio_method; | 
		
	
		
			
			|  |  |  | #endif | 
		
	
		
			
			|  |  |  | } TLSContext; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | #if HAVE_THREADS | 
		
	
	
		
			
				|  |  | @@ -63,6 +66,87 @@ static unsigned long openssl_thread_id(void) | 
		
	
		
			
			|  |  |  | #endif | 
		
	
		
			
			|  |  |  | #endif | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | static int url_bio_create(BIO *b) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | #if OPENSSL_VERSION_NUMBER >= 0x1010000fL | 
		
	
		
			
			|  |  |  | BIO_set_init(b, 1); | 
		
	
		
			
			|  |  |  | BIO_set_data(b, NULL); | 
		
	
		
			
			|  |  |  | BIO_set_flags(b, 0); | 
		
	
		
			
			|  |  |  | #else | 
		
	
		
			
			|  |  |  | b->init = 1; | 
		
	
		
			
			|  |  |  | b->ptr = NULL; | 
		
	
		
			
			|  |  |  | b->flags = 0; | 
		
	
		
			
			|  |  |  | #endif | 
		
	
		
			
			|  |  |  | return 1; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | static int url_bio_destroy(BIO *b) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | return 1; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | #if OPENSSL_VERSION_NUMBER >= 0x1010000fL | 
		
	
		
			
			|  |  |  | #define GET_BIO_DATA(x) BIO_get_data(x); | 
		
	
		
			
			|  |  |  | #else | 
		
	
		
			
			|  |  |  | #define GET_BIO_DATA(x) (x)->ptr; | 
		
	
		
			
			|  |  |  | #endif | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | static int url_bio_bread(BIO *b, char *buf, int len) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | URLContext *h; | 
		
	
		
			
			|  |  |  | int ret; | 
		
	
		
			
			|  |  |  | h = GET_BIO_DATA(b); | 
		
	
		
			
			|  |  |  | ret = ffurl_read(h, buf, len); | 
		
	
		
			
			|  |  |  | if (ret >= 0) | 
		
	
		
			
			|  |  |  | return ret; | 
		
	
		
			
			|  |  |  | BIO_clear_retry_flags(b); | 
		
	
		
			
			|  |  |  | if (ret == AVERROR_EXIT) | 
		
	
		
			
			|  |  |  | return 0; | 
		
	
		
			
			|  |  |  | return -1; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | static int url_bio_bwrite(BIO *b, const char *buf, int len) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | URLContext *h; | 
		
	
		
			
			|  |  |  | int ret; | 
		
	
		
			
			|  |  |  | h = GET_BIO_DATA(b); | 
		
	
		
			
			|  |  |  | ret = ffurl_write(h, buf, len); | 
		
	
		
			
			|  |  |  | if (ret >= 0) | 
		
	
		
			
			|  |  |  | return ret; | 
		
	
		
			
			|  |  |  | BIO_clear_retry_flags(b); | 
		
	
		
			
			|  |  |  | if (ret == AVERROR_EXIT) | 
		
	
		
			
			|  |  |  | return 0; | 
		
	
		
			
			|  |  |  | return -1; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | static long url_bio_ctrl(BIO *b, int cmd, long num, void *ptr) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | if (cmd == BIO_CTRL_FLUSH) { | 
		
	
		
			
			|  |  |  | BIO_clear_retry_flags(b); | 
		
	
		
			
			|  |  |  | return 1; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | return 0; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | static int url_bio_bputs(BIO *b, const char *str) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | return url_bio_bwrite(b, str, strlen(str)); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | #if OPENSSL_VERSION_NUMBER < 0x1010000fL | 
		
	
		
			
			|  |  |  | static BIO_METHOD url_bio_method = { | 
		
	
		
			
			|  |  |  | .type = BIO_TYPE_SOURCE_SINK, | 
		
	
		
			
			|  |  |  | .name = "urlprotocol bio", | 
		
	
		
			
			|  |  |  | .bwrite = url_bio_bwrite, | 
		
	
		
			
			|  |  |  | .bread = url_bio_bread, | 
		
	
		
			
			|  |  |  | .bputs = url_bio_bputs, | 
		
	
		
			
			|  |  |  | .bgets = NULL, | 
		
	
		
			
			|  |  |  | .ctrl = url_bio_ctrl, | 
		
	
		
			
			|  |  |  | .create = url_bio_create, | 
		
	
		
			
			|  |  |  | .destroy = url_bio_destroy, | 
		
	
		
			
			|  |  |  | }; | 
		
	
		
			
			|  |  |  | #endif | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | int ff_openssl_init(void) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | avpriv_lock_avformat(); | 
		
	
	
		
			
				|  |  | @@ -128,73 +212,14 @@ static int tls_close(URLContext *h) | 
		
	
		
			
			|  |  |  | SSL_CTX_free(c->ctx); | 
		
	
		
			
			|  |  |  | if (c->tls_shared.tcp) | 
		
	
		
			
			|  |  |  | ffurl_close(c->tls_shared.tcp); | 
		
	
		
			
			|  |  |  | #if OPENSSL_VERSION_NUMBER >= 0x1010000fL | 
		
	
		
			
			|  |  |  | if (c->url_bio_method) | 
		
	
		
			
			|  |  |  | BIO_meth_free(c->url_bio_method); | 
		
	
		
			
			|  |  |  | #endif | 
		
	
		
			
			|  |  |  | ff_openssl_deinit(); | 
		
	
		
			
			|  |  |  | return 0; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | static int url_bio_create(BIO *b) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | b->init = 1; | 
		
	
		
			
			|  |  |  | b->ptr = NULL; | 
		
	
		
			
			|  |  |  | b->flags = 0; | 
		
	
		
			
			|  |  |  | return 1; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | static int url_bio_destroy(BIO *b) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | return 1; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | static int url_bio_bread(BIO *b, char *buf, int len) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | URLContext *h = b->ptr; | 
		
	
		
			
			|  |  |  | int ret = ffurl_read(h, buf, len); | 
		
	
		
			
			|  |  |  | if (ret >= 0) | 
		
	
		
			
			|  |  |  | return ret; | 
		
	
		
			
			|  |  |  | BIO_clear_retry_flags(b); | 
		
	
		
			
			|  |  |  | if (ret == AVERROR_EXIT) | 
		
	
		
			
			|  |  |  | return 0; | 
		
	
		
			
			|  |  |  | return -1; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | static int url_bio_bwrite(BIO *b, const char *buf, int len) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | URLContext *h = b->ptr; | 
		
	
		
			
			|  |  |  | int ret = ffurl_write(h, buf, len); | 
		
	
		
			
			|  |  |  | if (ret >= 0) | 
		
	
		
			
			|  |  |  | return ret; | 
		
	
		
			
			|  |  |  | BIO_clear_retry_flags(b); | 
		
	
		
			
			|  |  |  | if (ret == AVERROR_EXIT) | 
		
	
		
			
			|  |  |  | return 0; | 
		
	
		
			
			|  |  |  | return -1; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | static long url_bio_ctrl(BIO *b, int cmd, long num, void *ptr) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | if (cmd == BIO_CTRL_FLUSH) { | 
		
	
		
			
			|  |  |  | BIO_clear_retry_flags(b); | 
		
	
		
			
			|  |  |  | return 1; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | return 0; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | static int url_bio_bputs(BIO *b, const char *str) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | return url_bio_bwrite(b, str, strlen(str)); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | static BIO_METHOD url_bio_method = { | 
		
	
		
			
			|  |  |  | .type = BIO_TYPE_SOURCE_SINK, | 
		
	
		
			
			|  |  |  | .name = "urlprotocol bio", | 
		
	
		
			
			|  |  |  | .bwrite = url_bio_bwrite, | 
		
	
		
			
			|  |  |  | .bread = url_bio_bread, | 
		
	
		
			
			|  |  |  | .bputs = url_bio_bputs, | 
		
	
		
			
			|  |  |  | .bgets = NULL, | 
		
	
		
			
			|  |  |  | .ctrl = url_bio_ctrl, | 
		
	
		
			
			|  |  |  | .create = url_bio_create, | 
		
	
		
			
			|  |  |  | .destroy = url_bio_destroy, | 
		
	
		
			
			|  |  |  | }; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | TLSContext *p = h->priv_data; | 
		
	
	
		
			
				|  |  | @@ -240,8 +265,20 @@ static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **op | 
		
	
		
			
			|  |  |  | ret = AVERROR(EIO); | 
		
	
		
			
			|  |  |  | goto fail; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | #if OPENSSL_VERSION_NUMBER >= 0x1010000fL | 
		
	
		
			
			|  |  |  | p->url_bio_method = BIO_meth_new(BIO_TYPE_SOURCE_SINK, "urlprotocol bio"); | 
		
	
		
			
			|  |  |  | BIO_meth_set_write(p->url_bio_method, url_bio_bwrite); | 
		
	
		
			
			|  |  |  | BIO_meth_set_read(p->url_bio_method, url_bio_bread); | 
		
	
		
			
			|  |  |  | BIO_meth_set_puts(p->url_bio_method, url_bio_bputs); | 
		
	
		
			
			|  |  |  | BIO_meth_set_ctrl(p->url_bio_method, url_bio_ctrl); | 
		
	
		
			
			|  |  |  | BIO_meth_set_create(p->url_bio_method, url_bio_create); | 
		
	
		
			
			|  |  |  | BIO_meth_set_destroy(p->url_bio_method, url_bio_destroy); | 
		
	
		
			
			|  |  |  | bio = BIO_new(p->url_bio_method); | 
		
	
		
			
			|  |  |  | BIO_set_data(bio, c->tcp); | 
		
	
		
			
			|  |  |  | #else | 
		
	
		
			
			|  |  |  | bio = BIO_new(&url_bio_method); | 
		
	
		
			
			|  |  |  | bio->ptr = c->tcp; | 
		
	
		
			
			|  |  |  | #endif | 
		
	
		
			
			|  |  |  | SSL_set_bio(p->ssl, bio, bio); | 
		
	
		
			
			|  |  |  | if (!c->listen && !c->numerichost) | 
		
	
		
			
			|  |  |  | SSL_set_tlsext_host_name(p->ssl, c->host); | 
		
	
	
		
			
				|  |  | 
 |