@ -36,6 +36,33 @@
if ( c - > cred ) \
gnutls_certificate_free_credentials ( c - > cred ) ; \
} while ( 0 )
static ssize_t gnutls_url_pull ( gnutls_transport_ptr_t transport ,
void * buf , size_t len )
{
URLContext * h = ( URLContext * ) transport ;
int ret = ffurl_read ( h , buf , len ) ;
if ( ret > = 0 )
return ret ;
if ( ret = = AVERROR ( EAGAIN ) )
errno = EAGAIN ;
else
errno = EIO ;
return - 1 ;
}
static ssize_t gnutls_url_push ( gnutls_transport_ptr_t transport ,
const void * buf , size_t len )
{
URLContext * h = ( URLContext * ) transport ;
int ret = ffurl_write ( h , buf , len ) ;
if ( ret > = 0 )
return ret ;
if ( ret = = AVERROR ( EAGAIN ) )
errno = EAGAIN ;
else
errno = EIO ;
return - 1 ;
}
# elif CONFIG_OPENSSL
# include <openssl/bio.h>
# include <openssl/ssl.h>
@ -49,6 +76,70 @@
if ( c - > ctx ) \
SSL_CTX_free ( c - > ctx ) ; \
} while ( 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 ( EAGAIN ) )
BIO_set_retry_read ( b ) ;
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 ( EAGAIN ) )
BIO_set_retry_write ( b ) ;
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 ,
} ;
# endif
# include "network.h"
# include "os_support.h"
@ -148,6 +239,9 @@ static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **op
struct addrinfo hints = { 0 } , * ai = NULL ;
const char * proxy_path ;
int use_proxy ;
# if CONFIG_OPENSSL
BIO * bio ;
# endif
ff_tls_init ( ) ;
@ -220,8 +314,10 @@ static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **op
}
}
gnutls_credentials_set ( c - > session , GNUTLS_CRD_CERTIFICATE , c - > cred ) ;
gnutls_transport_set_ptr ( c - > session , ( gnutls_transport_ptr_t )
( intptr_t ) c - > fd ) ;
c - > tcp - > flags | = AVIO_FLAG_NONBLOCK ;
gnutls_transport_set_pull_function ( c - > session , gnutls_url_pull ) ;
gnutls_transport_set_push_function ( c - > session , gnutls_url_push ) ;
gnutls_transport_set_ptr ( c - > session , c - > tcp ) ;
gnutls_priority_set_direct ( c - > session , " NORMAL " , NULL ) ;
while ( 1 ) {
ret = gnutls_handshake ( c - > session ) ;
@ -293,7 +389,10 @@ static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **op
ret = AVERROR ( EIO ) ;
goto fail ;
}
SSL_set_fd ( c - > ssl , c - > fd ) ;
bio = BIO_new ( & url_bio_method ) ;
c - > tcp - > flags | = AVIO_FLAG_NONBLOCK ;
bio - > ptr = c - > tcp ;
SSL_set_bio ( c - > ssl , bio , bio ) ;
if ( ! c - > listen & & ! numerichost )
SSL_set_tlsext_host_name ( c - > ssl , host ) ;
while ( 1 ) {