#include <vlc_acl.h>
#include <vlc_strings.h>
#include <vlc_rand.h>
+#include <vlc_charset.h>
#include "../libvlc.h"
#include <string.h>
static void httpd_ClientClean( httpd_client_t *cl );
-struct httpd_t
-{
- VLC_COMMON_MEMBERS
-
- int i_host;
- httpd_host_t **host;
-};
-
-
/* each host run in his own thread */
struct httpd_host_t
{
VLC_COMMON_MEMBERS
- httpd_t *httpd;
-
/* ref count */
unsigned i_ref;
/* address/port and socket for listening at connections */
- char *psz_hostname;
- int i_port;
int *fds;
unsigned nfd;
+ unsigned port;
vlc_thread_t thread;
vlc_mutex_t lock;
httpd_client_t **client;
/* TLS data */
- tls_server_t *p_tls;
+ vlc_tls_creds_t *p_tls;
};
{
HTTPD_CLIENT_FILE, /* default */
HTTPD_CLIENT_STREAM, /* regulary get data from cb */
- HTTPD_CLIENT_BIDIR, /* check for reading and get data from cb */
};
struct httpd_client_t
int fd;
- int i_mode;
- int i_state;
- int b_read_waiting; /* stop as soon as possible sending */
+ bool b_stream_mode;
+ uint8_t i_state;
mtime_t i_activity_date;
mtime_t i_activity_timeout;
httpd_message_t answer; /* httpd -> client */
/* TLS data */
- tls_session_t *p_tls;
+ vlc_tls_t *p_tls;
};
{ 452, "Conference not found" },
{ 453, "Not enough bandwidth" },*/
{ 454, "Session not found" },
- /*{ 455, "Method not valid in this State" },*/
+ { 455, "Method not valid in this State" },
{ 456, "Header field not valid for resource" },
- /*{ 457, "Invalid range" },
- { 458, "Read-only parameter" },*/
+ { 457, "Invalid range" },
+ /*{ 458, "Read-only parameter" },*/
{ 459, "Aggregate operation not allowed" },
{ 460, "Non-aggregate operation not allowed" },
{ 461, "Unsupported transport" },
/* We do it ourselves, thanks */
answer->i_status = 0;
- if( httpd_ClientIP( cl, psz_remote_addr ) == NULL )
+ if( httpd_ClientIP( cl, psz_remote_addr, NULL ) == NULL )
*psz_remote_addr = '\0';
uint8_t *psz_args = query->psz_args;
if( query->i_type != HTTPD_MSG_HEAD )
{
- httpd_ClientModeStream( cl );
+ cl->b_stream_mode = true;
vlc_mutex_lock( &stream->lock );
/* Send the header */
if( stream->i_header > 0 )
* Low level
*****************************************************************************/
static void* httpd_HostThread( void * );
+static httpd_host_t *httpd_HostCreate( vlc_object_t *, const char *,
+ const char *, vlc_tls_creds_t * );
/* create a new host */
-httpd_host_t *httpd_HostNew( vlc_object_t *p_this, const char *psz_host,
- int i_port )
+httpd_host_t *vlc_http_HostNew( vlc_object_t *p_this )
{
- return httpd_TLSHostNew( p_this, psz_host, i_port, NULL, NULL, NULL, NULL
- );
+ return httpd_HostCreate( p_this, "http-host", "http-port", NULL );
}
-static const char psz_object_type[] = "http server";
-static vlc_mutex_t httpd_mutex = VLC_STATIC_MUTEX;
-
-httpd_host_t *httpd_TLSHostNew( vlc_object_t *p_this, const char *psz_hostname,
- int i_port,
- const char *psz_cert, const char *psz_key,
- const char *psz_ca, const char *psz_crl )
+httpd_host_t *vlc_https_HostNew( vlc_object_t *obj )
{
- httpd_t *httpd;
- httpd_host_t *host;
- tls_server_t *p_tls;
- char *psz_host;
- vlc_value_t ptrval;
- int i;
+ char *cert = var_InheritString( obj, "http-cert" );
+ if( cert == NULL )
+ {
+ msg_Err( obj, "HTTP/TLS certificate not specified!" );
+ return NULL;
+ }
- if( psz_hostname == NULL )
- psz_hostname = "";
+ char *key = var_InheritString( obj, "http-key" );
+ vlc_tls_creds_t *tls = vlc_tls_ServerCreate( obj, cert, key );
- psz_host = strdup( psz_hostname );
- if( psz_host == NULL )
+ if( tls == NULL )
+ {
+ msg_Err( obj, "HTTP/TLS certificate error (%s and %s)",
+ cert, (key != NULL) ? key : cert );
+ free( key );
+ free( cert );
return NULL;
+ }
+ free( key );
+ free( cert );
- /* to be sure to avoid multiple creation */
- vlc_mutex_lock( &httpd_mutex );
- httpd = libvlc_priv (p_this->p_libvlc)->p_httpd;
+ char *ca = var_InheritString( obj, "http-ca" );
+ if( ca != NULL )
+ {
+ if( vlc_tls_ServerAddCA( tls, ca ) )
+ {
+ msg_Err( obj, "HTTP/TLS CA error (%s)", ca );
+ free( ca );
+ goto error;
+ }
+ free( ca );
+ }
- if( httpd == NULL )
+ char *crl = var_InheritString( obj, "http-crl" );
+ if( crl != NULL )
{
- msg_Info( p_this, "creating httpd" );
- httpd = (httpd_t *)vlc_custom_create( p_this, sizeof (*httpd),
- VLC_OBJECT_GENERIC,
- psz_object_type );
- if( httpd == NULL )
+ if( vlc_tls_ServerAddCRL( tls, crl ) )
{
- vlc_mutex_unlock( &httpd_mutex );
- free( psz_host );
- return NULL;
+ msg_Err( obj, "TLS CRL error (%s)", crl );
+ free( crl );
+ goto error;
}
+ free( crl );
+ }
- httpd->i_host = 0;
- httpd->host = NULL;
+ return httpd_HostCreate( obj, "http-host", "https-port", tls );
- ptrval.p_address = httpd;
- libvlc_priv (p_this->p_libvlc)->p_httpd = httpd;
- vlc_object_attach( httpd, p_this->p_libvlc );
- }
+error:
+ vlc_tls_ServerDelete( tls );
+ return NULL;
+}
+
+httpd_host_t *vlc_rtsp_HostNew( vlc_object_t *p_this )
+{
+ return httpd_HostCreate( p_this, "rtsp-host", "rtsp-port", NULL );
+}
+
+static struct httpd_t
+{
+ vlc_mutex_t mutex;
+
+ httpd_host_t **host;
+ int i_host;
+} httpd = { VLC_STATIC_MUTEX, NULL, 0 };
+
+static httpd_host_t *httpd_HostCreate( vlc_object_t *p_this,
+ const char *hostvar,
+ const char *portvar,
+ vlc_tls_creds_t *p_tls )
+{
+ httpd_host_t *host;
+ unsigned port = var_InheritInteger( p_this, portvar );
+
+ /* to be sure to avoid multiple creation */
+ vlc_mutex_lock( &httpd.mutex );
/* verify if it already exist */
- for( i = httpd->i_host - 1; i >= 0; i-- )
+ for( int i = 0; i < httpd.i_host; i++ )
{
- host = httpd->host[i];
+ host = httpd.host[i];
/* cannot mix TLS and non-TLS hosts */
- if( ( ( httpd->host[i]->p_tls != NULL ) != ( psz_cert != NULL ) )
- || ( host->i_port != i_port )
- || strcmp( host->psz_hostname, psz_hostname ) )
+ if( host->port != port
+ || (host->p_tls != NULL) != (p_tls != NULL) )
continue;
/* Increase existing matching host reference count.
host->i_ref++;
vlc_mutex_unlock( &host->lock );
- vlc_mutex_unlock( &httpd_mutex );
+ vlc_mutex_unlock( &httpd.mutex );
+ if( p_tls != NULL )
+ vlc_tls_ServerDelete( p_tls );
return host;
}
host = NULL;
- /* determine TLS configuration */
- if ( psz_cert != NULL )
- {
- p_tls = tls_ServerCreate( p_this, psz_cert, psz_key );
- if ( p_tls == NULL )
- {
- msg_Err( p_this, "TLS initialization error" );
- goto error;
- }
-
- if ( ( psz_ca != NULL) && tls_ServerAddCA( p_tls, psz_ca ) )
- {
- msg_Err( p_this, "TLS CA error" );
- goto error;
- }
-
- if ( ( psz_crl != NULL) && tls_ServerAddCRL( p_tls, psz_crl ) )
- {
- msg_Err( p_this, "TLS CRL error" );
- goto error;
- }
- }
- else
- p_tls = NULL;
-
/* create the new host */
host = (httpd_host_t *)vlc_custom_create( p_this, sizeof (*host),
- VLC_OBJECT_GENERIC,
- psz_object_type );
+ "http host" );
if (host == NULL)
goto error;
- host->httpd = httpd;
vlc_mutex_init( &host->lock );
vlc_cond_init( &host->wait );
host->i_ref = 1;
- vlc_object_attach( host, p_this );
-
- host->fds = net_ListenTCP( p_this, psz_host, i_port );
+ char *hostname = var_InheritString( p_this, hostvar );
+ host->fds = net_ListenTCP( p_this, hostname, port );
+ free( hostname );
if( host->fds == NULL )
{
msg_Err( p_this, "cannot create socket(s) for HTTP host" );
goto error;
}
- host->i_port = i_port;
- host->psz_hostname = psz_host;
-
- host->i_url = 0;
- host->url = NULL;
- host->i_client = 0;
- host->client = NULL;
-
- host->p_tls = p_tls;
+ host->port = port;
+ host->i_url = 0;
+ host->url = NULL;
+ host->i_client = 0;
+ host->client = NULL;
+ host->p_tls = p_tls;
/* create the thread */
if( vlc_clone( &host->thread, httpd_HostThread, host,
}
/* now add it to httpd */
- TAB_APPEND( httpd->i_host, httpd->host, host );
- vlc_mutex_unlock( &httpd_mutex );
+ TAB_APPEND( httpd.i_host, httpd.host, host );
+ vlc_mutex_unlock( &httpd.mutex );
return host;
error:
- free( psz_host );
- if( httpd->i_host <= 0 )
- {
- libvlc_priv (httpd->p_libvlc)->p_httpd = NULL;
- vlc_object_release( httpd );
- }
- vlc_mutex_unlock( &httpd_mutex );
+ vlc_mutex_unlock( &httpd.mutex );
if( host != NULL )
{
}
if( p_tls != NULL )
- tls_ServerDelete( p_tls );
+ vlc_tls_ServerDelete( p_tls );
return NULL;
}
/* delete a host */
void httpd_HostDelete( httpd_host_t *host )
{
- httpd_t *httpd = host->httpd;
int i;
bool delete = false;
- vlc_mutex_lock( &httpd_mutex );
+ vlc_mutex_lock( &httpd.mutex );
vlc_mutex_lock( &host->lock );
host->i_ref--;
if( !delete )
{
/* still used */
- vlc_mutex_unlock( &httpd_mutex );
+ vlc_mutex_unlock( &httpd.mutex );
msg_Dbg( host, "httpd_HostDelete: host still in use" );
return;
}
- TAB_REMOVE( httpd->i_host, httpd->host, host );
+ TAB_REMOVE( httpd.i_host, httpd.host, host );
vlc_object_kill( host );
vlc_join( host->thread, NULL );
}
if( host->p_tls != NULL)
- tls_ServerDelete( host->p_tls );
+ vlc_tls_ServerDelete( host->p_tls );
net_ListenClose( host->fds );
- free( host->psz_hostname );
-
vlc_cond_destroy( &host->wait );
vlc_mutex_destroy( &host->lock );
vlc_object_release( host );
-
- if( httpd->i_host <= 0 )
- {
- msg_Dbg( httpd, "no hosts left, stopping httpd" );
-
- libvlc_priv (httpd->p_libvlc)->p_httpd = NULL;
- vlc_object_release( httpd );
- }
- vlc_mutex_unlock( &httpd_mutex );
+ vlc_mutex_unlock( &httpd.mutex );
}
/* register a new url */
{
if( !strcmp( psz_url, host->url[i]->psz_url ) )
{
- msg_Warn( host->httpd,
+ msg_Warn( host,
"cannot add '%s' (url already defined)", psz_url );
vlc_mutex_unlock( &host->lock );
return NULL;
return VLC_SUCCESS;
}
-/* delete an url */
+/* delete a url */
void httpd_UrlDelete( httpd_url_t *url )
{
httpd_host_t *host = url->host;
msg->psz_url = NULL;
msg->psz_args = NULL;
- msg->i_channel = -1;
-
msg->i_name = 0;
msg->name = NULL;
msg->i_value = 0;
char *value = NULL;
va_start( args, psz_value );
- if( vasprintf( &value, psz_value, args ) == -1 )
+ if( us_vasprintf( &value, psz_value, args ) == -1 )
value = NULL;
va_end( args );
cl->i_buffer_size = HTTPD_CL_BUFSIZE;
cl->i_buffer = 0;
cl->p_buffer = xmalloc( cl->i_buffer_size );
- cl->i_mode = HTTPD_CLIENT_FILE;
- cl->b_read_waiting = false;
+ cl->b_stream_mode = false;
httpd_MsgInit( &cl->query );
httpd_MsgInit( &cl->answer );
}
-void httpd_ClientModeStream( httpd_client_t *cl )
-{
- cl->i_mode = HTTPD_CLIENT_STREAM;
-}
-
-void httpd_ClientModeBidir( httpd_client_t *cl )
+char* httpd_ClientIP( const httpd_client_t *cl, char *ip, int *port )
{
- cl->i_mode = HTTPD_CLIENT_BIDIR;
+ return net_GetPeerAddress( cl->fd, ip, port ) ? NULL : ip;
}
-char* httpd_ClientIP( const httpd_client_t *cl, char *psz_ip )
+char* httpd_ServerIP( const httpd_client_t *cl, char *ip, int *port )
{
- return net_GetPeerAddress( cl->fd, psz_ip, NULL ) ? NULL : psz_ip;
-}
-
-char* httpd_ServerIP( const httpd_client_t *cl, char *psz_ip )
-{
- return net_GetSockAddress( cl->fd, psz_ip, NULL ) ? NULL : psz_ip;
+ return net_GetSockAddress( cl->fd, ip, port ) ? NULL : ip;
}
static void httpd_ClientClean( httpd_client_t *cl )
if( cl->fd >= 0 )
{
if( cl->p_tls != NULL )
- tls_ServerSessionClose( cl->p_tls );
+ vlc_tls_ServerSessionDelete( cl->p_tls );
net_Close( cl->fd );
cl->fd = -1;
}
cl->p_buffer = NULL;
}
-static httpd_client_t *httpd_ClientNew( int fd, tls_session_t *p_tls, mtime_t now )
+static httpd_client_t *httpd_ClientNew( int fd, vlc_tls_t *p_tls, mtime_t now )
{
httpd_client_t *cl = malloc( sizeof( httpd_client_t ) );
static
ssize_t httpd_NetRecv (httpd_client_t *cl, uint8_t *p, size_t i_len)
{
- tls_session_t *p_tls;
+ vlc_tls_t *p_tls;
ssize_t val;
p_tls = cl->p_tls;
static
ssize_t httpd_NetSend (httpd_client_t *cl, const uint8_t *p, size_t i_len)
{
- tls_session_t *p_tls;
+ vlc_tls_t *p_tls;
ssize_t val;
p_tls = cl->p_tls;
cl->i_buffer += i_len;
}
- if( ( cl->i_buffer >= 4 ) && ( cl->p_buffer[0] == '$' ) )
- {
- /* Interleaved RTP over RTSP */
- cl->query.i_proto = HTTPD_PROTO_RTSP;
- cl->query.i_type = HTTPD_MSG_CHANNEL;
- cl->query.i_channel = cl->p_buffer[1];
- cl->query.i_body = (cl->p_buffer[2] << 8)|cl->p_buffer[3];
- cl->query.p_body = xmalloc( cl->query.i_body );
- cl->i_buffer -= 4;
- memcpy( cl->query.p_body, cl->p_buffer + 4, cl->i_buffer );
- }
- else
/* The smallest legal request is 7 bytes ("GET /\r\n"),
* this is the maximum we can ask at this point. */
if( cl->i_buffer >= 7 )
*p2++ = '\0';
}
if( !strncasecmp( p, ( cl->query.i_proto
- == HTTPD_PROTO_HTTP ) ? "http" : "rtsp", 4 )
- && p[4 + !!strchr( "sS", p[4] )] == ':' )
+ == HTTPD_PROTO_HTTP ) ? "http:" : "rtsp:", 5 ) )
{ /* Skip hier-part of URL (if present) */
- p = strchr( p, ':' ) + 1; /* skip URI scheme */
+ p += 5;
if( !strncmp( p, "//", 2 ) ) /* skip authority */
{ /* see RFC3986 §3.2 */
p += 2;
- while( *p && !strchr( "/?#", *p ) ) p++;
+ p += strcspn( p, "/?#" );
}
}
+ else
+ if( !strncasecmp( p, ( cl->query.i_proto
+ == HTTPD_PROTO_HTTP ) ? "https:" : "rtsps:", 6 ) )
+ { /* Skip hier-part of URL (if present) */
+ p += 6;
+ if( !strncmp( p, "//", 2 ) ) /* skip authority */
+ { /* see RFC3986 §3.2 */
+ p += 2;
+ p += strcspn( p, "/?#" );
+ }
+ }
+
cl->query.psz_url = strdup( p );
if( ( p3 = strchr( cl->query.psz_url, '?' ) ) )
{
}
if( cl->query.i_body > 0 )
{
- /* TODO Mhh, handle the case client will only send a
- * request and close the connection
- * to mark and of body (probably only RTSP) */
- cl->query.p_body = xmalloc( cl->query.i_body );
+ /* TODO Mhh, handle the case where the client only
+ * sends a request and closes the connection to
+ * mark the end of the body (probably only RTSP) */
+ cl->query.p_body = malloc( cl->query.i_body );
cl->i_buffer = 0;
+ if ( cl->query.p_body == NULL )
+ {
+ switch (cl->query.i_proto)
+ {
+ case HTTPD_PROTO_HTTP:
+ {
+ const uint8_t sorry[] =
+ "HTTP/1.1 413 Request Entity Too Large\r\n\r\n";
+ httpd_NetSend( cl, sorry, sizeof( sorry ) - 1 );
+ break;
+ }
+ case HTTPD_PROTO_RTSP:
+ {
+ const uint8_t sorry[] =
+ "RTSP/1.0 413 Request Entity Too Large\r\n\r\n";
+ httpd_NetSend( cl, sorry, sizeof( sorry ) - 1 );
+ break;
+ }
+ default:
+ assert( 0 );
+ }
+ i_len = 0; /* drop */
+ }
+ break;
}
else
{
if( cl->i_buffer >= cl->i_buffer_size )
{
- if( cl->answer.i_body == 0 && cl->answer.i_body_offset > 0 &&
- !cl->b_read_waiting )
+ if( cl->answer.i_body == 0 && cl->answer.i_body_offset > 0 )
{
/* catch more body data */
int i_msg = cl->query.i_type;
static void httpd_ClientTlsHsIn( httpd_client_t *cl )
{
- switch( tls_SessionContinueHandshake( cl->p_tls ) )
+ switch( vlc_tls_ServerSessionHandshake( cl->p_tls ) )
{
case 0:
cl->i_state = HTTPD_CLIENT_RECEIVING;
static void httpd_ClientTlsHsOut( httpd_client_t *cl )
{
- switch( tls_SessionContinueHandshake( cl->p_tls ) )
+ switch( vlc_tls_ServerSessionHandshake( cl->p_tls ) )
{
case 0:
cl->i_state = HTTPD_CLIENT_RECEIVING;
static void* httpd_HostThread( void *data )
{
httpd_host_t *host = data;
- tls_session_t *p_tls = NULL;
counter_t *p_total_counter = stats_CounterCreate( host, VLC_VAR_INTEGER, STATS_COUNTER );
counter_t *p_active_counter = stats_CounterCreate( host, VLC_VAR_INTEGER, STATS_COUNTER );
int evfd = vlc_object_waitpipe( VLC_OBJECT( host ) );
for( ;; )
{
- /* prepare a new TLS session */
- if( ( p_tls == NULL ) && ( host->p_tls != NULL ) )
- p_tls = tls_ServerSessionPrepare( host->p_tls );
-
struct pollfd ufd[host->nfd + host->i_client + 1];
unsigned nfd;
for( nfd = 0; nfd < host->nfd; nfd++ )
httpd_MsgInit( answer );
/* Handle what we received */
- if( (cl->i_mode != HTTPD_CLIENT_BIDIR) &&
- (i_msg == HTTPD_MSG_ANSWER || i_msg == HTTPD_MSG_CHANNEL) )
+ if( i_msg == HTTPD_MSG_ANSWER )
{
- /* we can only receive request from client when not
- * in BIDIR mode */
cl->url = NULL;
cl->i_state = HTTPD_CLIENT_DEAD;
}
- else if( i_msg == HTTPD_MSG_ANSWER )
- {
- /* We are in BIDIR mode, trigger the callback and then
- * check for new data */
- if( cl->url && cl->url->catch[i_msg].cb )
- {
- cl->url->catch[i_msg].cb( cl->url->catch[i_msg].p_sys,
- cl, NULL, query );
- }
- cl->i_state = HTTPD_CLIENT_WAITING;
- }
- else if( i_msg == HTTPD_MSG_CHANNEL )
- {
- /* We are in BIDIR mode, trigger the callback and then
- * check for new data */
- if( cl->url && cl->url->catch[i_msg].cb )
- {
- cl->url->catch[i_msg].cb( cl->url->catch[i_msg].p_sys,
- cl, NULL, query );
- }
- cl->i_state = HTTPD_CLIENT_WAITING;
- }
else if( i_msg == HTTPD_MSG_OPTIONS )
{
answer->i_body = 0;
answer->p_body = NULL;
- httpd_MsgAdd( answer, "Server", "%s", PACKAGE_STRING );
+ httpd_MsgAdd( answer, "Server", "VLC/%s", VERSION );
httpd_MsgAdd( answer, "Content-Length", "0" );
switch( query->i_proto )
{
char ip[NI_MAXNUMERICHOST];
- if( ( httpd_ClientIP( cl, ip ) == NULL )
+ if( ( httpd_ClientIP( cl, ip, NULL ) == NULL )
|| ACL_Check( url->p_acl, ip ) )
{
b_hosts_failed = true;
}
else if( cl->i_state == HTTPD_CLIENT_SEND_DONE )
{
- if( cl->i_mode == HTTPD_CLIENT_FILE || cl->answer.i_body_offset == 0 )
+ if( !cl->b_stream_mode || cl->answer.i_body_offset == 0 )
{
const char *psz_connection = httpd_MsgGet( &cl->answer, "Connection" );
const char *psz_query = httpd_MsgGet( &cl->query, "Connection" );
}
httpd_MsgClean( &cl->answer );
}
- else if( cl->b_read_waiting )
- {
- /* we have a message waiting for us to read it */
- httpd_MsgClean( &cl->answer );
- httpd_MsgClean( &cl->query );
-
- cl->i_buffer = 0;
- cl->i_buffer_size = 1000;
- free( cl->p_buffer );
- cl->p_buffer = xmalloc( cl->i_buffer_size );
- cl->i_state = HTTPD_CLIENT_RECEIVING;
- cl->b_read_waiting = false;
- }
else
{
int64_t i_offset = cl->answer.i_body_offset;
}
}
- /* Special for BIDIR mode we also check reading */
- if( cl->i_mode == HTTPD_CLIENT_BIDIR &&
- cl->i_state == HTTPD_CLIENT_SENDING )
- {
- pufd->events |= POLLIN;
- }
-
if (pufd->events != 0)
nfd++;
else
{
httpd_ClientTlsHsOut( cl );
}
-
- if( cl->i_mode == HTTPD_CLIENT_BIDIR &&
- cl->i_state == HTTPD_CLIENT_SENDING &&
- (pufd->revents & POLLIN) )
- {
- cl->b_read_waiting = true;
- }
}
vlc_mutex_unlock( &host->lock );
continue;
/* */
-#ifdef HAVE_ACCEPT4
- fd = accept4 (fd, NULL, NULL, SOCK_CLOEXEC);
- if (fd == -1 && errno == ENOSYS)
-#endif
- fd = accept (fd, NULL, NULL);
+ fd = vlc_accept (fd, NULL, NULL, true);
if (fd == -1)
continue;
+ setsockopt (fd, SOL_SOCKET, SO_REUSEADDR,
+ &(int){ 1 }, sizeof(int));
+
+ vlc_tls_t *p_tls;
- net_SetupSocket (fd);
- if( p_tls != NULL )
+ if( host->p_tls != NULL )
{
- switch( tls_ServerSessionHandshake( p_tls, fd ) )
+ p_tls = vlc_tls_ServerSessionCreate( host->p_tls, fd );
+ switch( vlc_tls_ServerSessionHandshake( p_tls ) )
{
case -1:
msg_Err( host, "Rejecting TLS connection" );
+ /* p_tls is destroyed implicitly */
net_Close( fd );
fd = -1;
p_tls = NULL;
- break;
+ continue;
case 1: /* missing input - most likely */
i_state = HTTPD_CLIENT_TLS_HS_IN;
i_state = HTTPD_CLIENT_TLS_HS_OUT;
break;
}
-
- if( (p_tls == NULL) != (host->p_tls == NULL) )
- break; // wasted TLS session, cannot accept() anymore
}
+ else
+ p_tls = NULL;
stats_UpdateInteger( host, p_total_counter, 1, NULL );
stats_UpdateInteger( host, p_active_counter, 1, NULL );
cl = httpd_ClientNew( fd, p_tls, now );
- p_tls = NULL;
vlc_mutex_lock( &host->lock );
TAB_APPEND( host->i_client, host->client, cl );
vlc_mutex_unlock( &host->lock );
if( i_state != -1 )
cl->i_state = i_state; // override state for TLS
-
- if (host->p_tls != NULL)
- break; // cannot accept further without new TLS session
}
}
- if( p_tls != NULL )
- tls_ServerSessionClose( p_tls );
if( p_total_counter )
stats_CounterClean( p_total_counter );
if( p_active_counter )