2001-04-20 17:02:48 +02:00
|
|
|
/*****************************************************************************
|
2002-03-01 01:33:18 +01:00
|
|
|
* network.h: interface to communicate with network plug-ins
|
2001-04-20 17:02:48 +02:00
|
|
|
*****************************************************************************
|
2002-03-01 01:33:18 +01:00
|
|
|
* Copyright (C) 2002 VideoLAN
|
* ALL: Better announce system
- The SAP handler now runs in a separate thread.
- RTP sessions can be announced with sap (sdp=sap://,name=...)
TODO: Make this more configurable
- Better SDP generation (the timestamp problem is not resolved)
About this, there is a problem : as, for a RTP session, the URI
is the complete SDP, if the session is recreated, as the URI has
changed, a new item is added to the playlist
- Experimental flow control algorithm :
It does not follow the "Recommended" implementation, as it needs
to count the sessions (to achieve this, we should make this work
together with the SAP listener)
It is disabled by default (use --sap-flow-control to enable).
When it is disabled, sap announcement interval is set by --sap-interval
* src/misc/net.c : created net_ReadNonBlock
* sap.c : Fixed memory problem
2004-04-18 20:21:09 +02:00
|
|
|
* $Id$
|
2001-04-20 17:02:48 +02:00
|
|
|
*
|
2001-12-27 04:47:09 +01:00
|
|
|
* Authors: Christophe Massiot <massiot@via.ecp.fr>
|
2003-11-07 18:44:43 +01:00
|
|
|
* Laurent Aimar <fenrir@via.ecp.fr>
|
2001-04-20 17:02:48 +02:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
|
|
|
|
*****************************************************************************/
|
|
|
|
|
2002-03-01 01:33:18 +01:00
|
|
|
/*****************************************************************************
|
|
|
|
* network_socket_t: structure passed to a network plug-in to define the
|
|
|
|
* kind of socket we want
|
|
|
|
*****************************************************************************/
|
2002-07-20 20:01:43 +02:00
|
|
|
struct network_socket_t
|
2002-03-01 01:33:18 +01:00
|
|
|
{
|
|
|
|
unsigned int i_type;
|
|
|
|
|
|
|
|
char * psz_bind_addr;
|
|
|
|
int i_bind_port;
|
|
|
|
|
|
|
|
char * psz_server_addr;
|
|
|
|
int i_server_port;
|
|
|
|
|
2003-08-01 01:44:49 +02:00
|
|
|
int i_ttl;
|
|
|
|
|
2002-03-01 01:33:18 +01:00
|
|
|
/* Return values */
|
|
|
|
int i_handle;
|
|
|
|
size_t i_mtu;
|
* ALL: the first libvlc commit.
As for video output 4, this breaks almost everything, but I'll slowly
do what remains to be fixed during the weekend.
Changes in vlc:
===============
* vlc is now a very small program (20 lines) which uses the libvlc API;
it is quite simple for the moment but can be extended in the future.
* interfaces, decoders, video outputs, etc. are now almost the same
objects (yes, I know, this is C++ redone in C) and are structured in
a tree. More about this later, but basically it allows the following
nice features:
- several interfaces
- several playlists with several outputs
- input plugins spawning helper interfaces (will be used for DVD menus)
- anything spawning anything; I swear there are useful uses for this!
* libvlc can be used in other programs; I'm currently writing a Mozilla
plugin for my employer.
Things currently broken:
========================
* most interfaces, most ports
* the playlist handling (almost finished rewriting this though). This means
no file can be played from the GUI, you need to use the commandline. This
also means it segfaults at EOF, when exiting the program, and it sometimes
refuses to open a file when asked to.
2002-06-01 14:32:02 +02:00
|
|
|
};
|
2002-03-01 01:33:18 +01:00
|
|
|
|
|
|
|
/* Socket types */
|
|
|
|
#define NETWORK_UDP 1
|
|
|
|
#define NETWORK_TCP 2
|
2004-06-06 14:45:32 +02:00
|
|
|
#define NETWORK_TCP_PASSIVE 3
|
2002-03-01 01:33:18 +01:00
|
|
|
|
2003-11-07 18:44:43 +01:00
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
char *psz_protocol;
|
|
|
|
char *psz_host;
|
|
|
|
int i_port;
|
|
|
|
|
|
|
|
char *psz_path;
|
|
|
|
|
|
|
|
char *psz_option;
|
|
|
|
} vlc_url_t;
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
* vlc_UrlParse:
|
|
|
|
*****************************************************************************
|
|
|
|
* option : if != 0 then path is split at this char
|
|
|
|
*
|
2004-01-07 00:03:17 +01:00
|
|
|
* format [protocol://][host[:port]]/path[OPTIONoption]
|
2003-11-07 18:44:43 +01:00
|
|
|
*****************************************************************************/
|
|
|
|
static inline void vlc_UrlParse( vlc_url_t *url, char *psz_url, char option )
|
|
|
|
{
|
2004-09-11 15:15:18 +02:00
|
|
|
char *psz_dup = psz_url ? strdup( psz_url ) : 0;
|
2003-11-07 18:44:43 +01:00
|
|
|
char *psz_parse = psz_dup;
|
|
|
|
char *p;
|
|
|
|
|
|
|
|
url->psz_protocol = NULL;
|
|
|
|
url->psz_host = NULL;
|
|
|
|
url->i_port = 0;
|
|
|
|
url->psz_path = NULL;
|
|
|
|
url->psz_option = NULL;
|
|
|
|
|
2004-09-11 15:15:18 +02:00
|
|
|
if( !psz_url ) return;
|
|
|
|
|
2004-01-07 00:03:17 +01:00
|
|
|
if( ( p = strstr( psz_parse, ":/" ) ) )
|
2003-11-07 18:44:43 +01:00
|
|
|
{
|
|
|
|
/* we have a protocol */
|
|
|
|
|
|
|
|
/* skip :// */
|
|
|
|
*p++ = '\0';
|
|
|
|
if( p[0] == '/' && p[1] == '/' )
|
|
|
|
{
|
|
|
|
p += 2;
|
|
|
|
}
|
|
|
|
url->psz_protocol = strdup( psz_dup );
|
|
|
|
|
|
|
|
psz_parse = p;
|
2004-01-07 00:03:17 +01:00
|
|
|
}
|
2003-11-07 18:44:43 +01:00
|
|
|
|
2004-01-07 00:03:17 +01:00
|
|
|
p = strchr( psz_parse, '/' );
|
|
|
|
if( !p || psz_parse < p )
|
|
|
|
{
|
|
|
|
char *p2;
|
2003-11-07 18:44:43 +01:00
|
|
|
|
2004-01-07 00:03:17 +01:00
|
|
|
/* We have a host[:port] */
|
|
|
|
url->psz_host = strdup( psz_parse );
|
|
|
|
if( p )
|
|
|
|
{
|
|
|
|
url->psz_host[p - psz_parse] = '\0';
|
2003-11-07 18:44:43 +01:00
|
|
|
}
|
|
|
|
|
2004-01-07 00:11:47 +01:00
|
|
|
if( *url->psz_host == '[' )
|
|
|
|
{
|
|
|
|
/* Ipv6 address */
|
|
|
|
p2 = strchr( url->psz_host, ']' );
|
|
|
|
if( p2 )
|
|
|
|
{
|
|
|
|
p2 = strchr( p2, ':' );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
p2 = strchr( url->psz_host, ':' );
|
|
|
|
}
|
2004-01-07 00:03:17 +01:00
|
|
|
if( p2 )
|
|
|
|
{
|
|
|
|
*p2++ = '\0';
|
|
|
|
url->i_port = atoi( p2 );
|
|
|
|
}
|
|
|
|
}
|
2004-01-15 23:39:50 +01:00
|
|
|
psz_parse = p;
|
2003-11-07 18:44:43 +01:00
|
|
|
|
|
|
|
/* Now parse psz_path and psz_option */
|
|
|
|
if( psz_parse )
|
|
|
|
{
|
|
|
|
url->psz_path = strdup( psz_parse );
|
|
|
|
if( option != '\0' )
|
|
|
|
{
|
|
|
|
p = strchr( url->psz_path, option );
|
|
|
|
if( p )
|
|
|
|
{
|
|
|
|
*p++ = '\0';
|
|
|
|
url->psz_option = strdup( p );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free( psz_dup );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
* vlc_UrlClean:
|
|
|
|
*****************************************************************************
|
|
|
|
*
|
|
|
|
*****************************************************************************/
|
|
|
|
static inline void vlc_UrlClean( vlc_url_t *url )
|
|
|
|
{
|
|
|
|
if( url->psz_protocol ) free( url->psz_protocol );
|
|
|
|
if( url->psz_host ) free( url->psz_host );
|
|
|
|
if( url->psz_path ) free( url->psz_path );
|
|
|
|
if( url->psz_option ) free( url->psz_option );
|
|
|
|
|
|
|
|
url->psz_protocol = NULL;
|
|
|
|
url->psz_host = NULL;
|
|
|
|
url->i_port = 0;
|
|
|
|
url->psz_path = NULL;
|
|
|
|
url->psz_option = NULL;
|
|
|
|
}
|
2004-10-06 15:41:57 +02:00
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
* vlc_b64_encode:
|
|
|
|
*****************************************************************************
|
|
|
|
*
|
|
|
|
*****************************************************************************/
|
|
|
|
static inline char *vlc_b64_encode( unsigned char *src )
|
|
|
|
{
|
|
|
|
static const char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
|
|
|
|
|
|
char *dst = malloc( strlen( src ) * 4 / 3 + 12 );
|
|
|
|
char *ret = dst;
|
|
|
|
unsigned i_bits = 0;
|
|
|
|
unsigned i_shift = 0;
|
|
|
|
|
|
|
|
for( ;; )
|
|
|
|
{
|
|
|
|
if( *src )
|
|
|
|
{
|
|
|
|
i_bits = ( i_bits << 8 )|( *src++ );
|
|
|
|
i_shift += 8;
|
|
|
|
}
|
|
|
|
else if( i_shift > 0 )
|
|
|
|
{
|
|
|
|
i_bits <<= 6 - i_shift;
|
|
|
|
i_shift = 6;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*dst++ = '=';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
while( i_shift >= 6 )
|
|
|
|
{
|
|
|
|
i_shift -= 6;
|
|
|
|
*dst++ = b64[(i_bits >> i_shift)&0x3f];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*dst++ = '\0';
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
2003-11-07 18:44:43 +01:00
|
|
|
|
2004-11-07 12:02:59 +01:00
|
|
|
|
|
|
|
/* Portable networking layer communication */
|
2004-01-05 15:10:58 +01:00
|
|
|
#define net_OpenTCP(a, b, c) __net_OpenTCP(VLC_OBJECT(a), b, c)
|
2004-10-06 15:41:57 +02:00
|
|
|
VLC_EXPORT( int, __net_OpenTCP, ( vlc_object_t *p_this, const char *psz_host, int i_port ) );
|
2004-01-05 15:10:58 +01:00
|
|
|
|
2004-06-06 14:45:32 +02:00
|
|
|
#define net_ListenTCP(a, b, c) __net_ListenTCP(VLC_OBJECT(a), b, c)
|
|
|
|
VLC_EXPORT( int, __net_ListenTCP, ( vlc_object_t *p_this, char *psz_localaddr, int i_port ) );
|
|
|
|
|
2004-07-25 00:49:28 +02:00
|
|
|
#define net_Accept(a, b, c) __net_Accept(VLC_OBJECT(a), b, c)
|
|
|
|
VLC_EXPORT( int, __net_Accept, ( vlc_object_t *p_this, int fd_listen, mtime_t i_wait ) );
|
|
|
|
|
2004-01-21 11:22:31 +01:00
|
|
|
#define net_OpenUDP(a, b, c, d, e ) __net_OpenUDP(VLC_OBJECT(a), b, c, d, e)
|
|
|
|
VLC_EXPORT( int, __net_OpenUDP, ( vlc_object_t *p_this, char *psz_bind, int i_bind, char *psz_server, int i_server ) );
|
|
|
|
|
2004-01-05 15:10:58 +01:00
|
|
|
VLC_EXPORT( void, net_Close, ( int fd ) );
|
|
|
|
|
|
|
|
|
2004-11-07 12:02:59 +01:00
|
|
|
/* Functions to read from or write to the networking layer */
|
|
|
|
struct virtual_socket_t
|
|
|
|
{
|
|
|
|
void *p_sys;
|
|
|
|
int (*pf_recv) ( void *, void *, int );
|
|
|
|
int (*pf_send) ( void *, const void *, int );
|
|
|
|
};
|
|
|
|
|
|
|
|
#define net_Read(a,b,c,d,e,f) __net_Read(VLC_OBJECT(a),b,c,d,e,f)
|
|
|
|
VLC_EXPORT( int, __net_Read, ( vlc_object_t *p_this, int fd, v_socket_t *, uint8_t *p_data, int i_data, vlc_bool_t b_retry ) );
|
* ALL: Better announce system
- The SAP handler now runs in a separate thread.
- RTP sessions can be announced with sap (sdp=sap://,name=...)
TODO: Make this more configurable
- Better SDP generation (the timestamp problem is not resolved)
About this, there is a problem : as, for a RTP session, the URI
is the complete SDP, if the session is recreated, as the URI has
changed, a new item is added to the playlist
- Experimental flow control algorithm :
It does not follow the "Recommended" implementation, as it needs
to count the sessions (to achieve this, we should make this work
together with the SAP listener)
It is disabled by default (use --sap-flow-control to enable).
When it is disabled, sap announcement interval is set by --sap-interval
* src/misc/net.c : created net_ReadNonBlock
* sap.c : Fixed memory problem
2004-04-18 20:21:09 +02:00
|
|
|
|
2004-11-07 12:02:59 +01:00
|
|
|
#define net_ReadNonBlock(a,b,c,d,e,f) __net_ReadNonBlock(VLC_OBJECT(a),b,c,d,e,f)
|
|
|
|
VLC_EXPORT( int, __net_ReadNonBlock, ( vlc_object_t *p_this, int fd, v_socket_t *, uint8_t *p_data, int i_data, mtime_t i_wait ) );
|
2004-11-06 12:13:23 +01:00
|
|
|
|
2004-11-07 12:02:59 +01:00
|
|
|
#define net_Select(a,b,c,d,e,f,g) __net_Select(VLC_OBJECT(a),b,c,d,e,f,g)
|
|
|
|
VLC_EXPORT( int, __net_Select, ( vlc_object_t *p_this, int *pi_fd, v_socket_t **, int i_fd, uint8_t *p_data, int i_data, mtime_t i_wait ) );
|
2004-11-06 12:13:23 +01:00
|
|
|
|
2004-11-07 12:02:59 +01:00
|
|
|
#define net_Write(a,b,c,d,e) __net_Write(VLC_OBJECT(a),b,c,d,e)
|
|
|
|
VLC_EXPORT( int, __net_Write, ( vlc_object_t *p_this, int fd, v_socket_t *, uint8_t *p_data, int i_data ) );
|
2004-01-05 15:10:58 +01:00
|
|
|
|
2004-11-07 12:02:59 +01:00
|
|
|
#define net_Gets(a,b,c) __net_Gets(VLC_OBJECT(a),b,c)
|
|
|
|
VLC_EXPORT( char *, __net_Gets, ( vlc_object_t *p_this, int fd, v_socket_t * ) );
|
2004-01-05 15:10:58 +01:00
|
|
|
|
2004-11-07 12:02:59 +01:00
|
|
|
VLC_EXPORT( int, net_Printf, ( vlc_object_t *p_this, int fd, v_socket_t *, const char *psz_fmt, ... ) );
|
2004-01-05 15:10:58 +01:00
|
|
|
|
2004-11-07 12:02:59 +01:00
|
|
|
#define net_vaPrintf(a,b,c,d,e) __net_vaPrintf(VLC_OBJECT(a),b,c,d,e)
|
|
|
|
VLC_EXPORT( int, __net_vaPrintf, ( vlc_object_t *p_this, int fd, v_socket_t *, const char *psz_fmt, va_list args ) );
|