X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fmisc%2Fsap.c;h=e1981bf4d86a426a67f400516304e6227e5c2ecc;hb=d5d59ea9a5c5fbbc3c7011e5e5f4b846d9a355f9;hp=a56cf6a0046e368fa584aaa40dd28b0527537193;hpb=3f41f383e3162cf1984ed39981fbc4ed2afe6613;p=vlc diff --git a/modules/misc/sap.c b/modules/misc/sap.c index a56cf6a004..e1981bf4d8 100644 --- a/modules/misc/sap.c +++ b/modules/misc/sap.c @@ -1,8 +1,9 @@ + /***************************************************************************** * sap.c : SAP interface module ***************************************************************************** * Copyright (C) 2001 VideoLAN - * $Id: sap.c,v 1.30 2003/11/05 23:28:36 fenrir Exp $ + * $Id$ * * Authors: Arnaud Schauly * Clément Stenac @@ -66,6 +67,10 @@ #include "network.h" +#ifdef HAVE_ZLIB_H +# include +#endif + #define MAX_LINE_LENGTH 256 /* SAP is always on that port */ @@ -83,30 +88,36 @@ #define SAP_ADDR_TEXT N_("SAP multicast address") #define SAP_ADDR_LONGTEXT N_("SAP multicast address") #define SAP_IPV4_TEXT N_("IPv4-SAP listening") -#define SAP_IPV4_LONGTEXT N_("Set this if you want SAP to listen for IPv4 announces") -#define SAP_IPV6_TEXT N_("IPv6-SAP listening") -#define SAP_IPV6_LONGTEXT N_("Set this if you want SAP to listen for IPv6 announces") +#define SAP_IPV4_LONGTEXT N_( \ + "Set this if you want the SAP module to listen to IPv4 announces") +#define SAP_IPV6_TEXT N_( "IPv6-SAP listening") +#define SAP_IPV6_LONGTEXT N_(\ + "Set this if you want the SAP module to listen to IPv6 announces") #define SAP_SCOPE_TEXT N_("IPv6 SAP scope") -#define SAP_SCOPE_LONGTEXT N_("Sets the scope for IPv6 announces (default is 8)") +#define SAP_SCOPE_LONGTEXT N_( \ + "Sets the scope for IPv6 announces (default is 8)") +#define SAP_TIMEOUT_TEXT N_("SAP timeout (seconds)") +#define SAP_TIMEOUT_LONGTEXT N_( \ + "Sets the time before SAP items get deleted if no new announce " \ + "is received.") static int Open ( vlc_object_t * ); static void Close( vlc_object_t * ); vlc_module_begin(); - add_category_hint( N_("SAP"), NULL, VLC_TRUE ); - add_string( "sap-addr", NULL, NULL, - SAP_ADDR_TEXT, SAP_ADDR_LONGTEXT, VLC_TRUE ); - - add_bool( "sap-ipv4", 1 , NULL, - SAP_IPV4_TEXT,SAP_IPV4_LONGTEXT, VLC_TRUE); - - add_bool( "sap-ipv6", 0 , NULL, - SAP_IPV6_TEXT, SAP_IPV6_LONGTEXT, VLC_TRUE); + set_description( _("SAP interface") ); - add_string( "sap-ipv6-scope", "8" , NULL, - SAP_SCOPE_TEXT, SAP_SCOPE_LONGTEXT, VLC_TRUE); + add_string( "sap-addr", NULL, NULL, + SAP_ADDR_TEXT, SAP_ADDR_LONGTEXT, VLC_TRUE ); + add_bool( "sap-ipv4", 1 , NULL, + SAP_IPV4_TEXT,SAP_IPV4_LONGTEXT, VLC_TRUE); + add_bool( "sap-ipv6", 0 , NULL, + SAP_IPV6_TEXT, SAP_IPV6_LONGTEXT, VLC_TRUE); + add_string( "sap-ipv6-scope", "8" , NULL, + SAP_SCOPE_TEXT, SAP_SCOPE_LONGTEXT, VLC_TRUE); + add_integer( "sap-timeout", 1800, NULL, + SAP_TIMEOUT_TEXT, SAP_TIMEOUT_LONGTEXT, VLC_TRUE); - set_description( _("SAP interface") ); set_capability( "interface", 0 ); set_callbacks( Open, Close ); vlc_module_end(); @@ -116,7 +127,7 @@ vlc_module_end(); *****************************************************************************/ static void Run ( intf_thread_t *p_intf ); -static int NetRead( intf_thread_t *, int fd[2], uint8_t *, int ); +static ssize_t NetRead( intf_thread_t *, int fd[2], uint8_t *, int ); typedef struct media_descr_t media_descr_t; typedef struct sess_descr_t sess_descr_t; @@ -136,6 +147,7 @@ struct sess_descr_t int i_version; char *psz_sessionname; char *psz_connection; + char *psz_sdp; int i_media; media_descr_t **pp_media; @@ -156,6 +168,14 @@ struct attr_descr_t char *psz_value; }; +struct sap_announce_t +{ + mtime_t i_last; + int i_id; + char *psz_name; + char *psz_uri; +}; + struct intf_sys_t { /* IPV4 and IPV6 */ @@ -163,8 +183,55 @@ struct intf_sys_t /* playlist group */ int i_group; + + /* Table of announces */ + int i_announces; + struct sap_announce_t **pp_announces; + + int i_timeout; }; +#ifdef HAVE_ZLIB_H +int do_decompress(unsigned char *src, unsigned char **_dst, int slen) { + int result, dstsize, n; + unsigned char *dst; + z_stream d_stream; + + d_stream.zalloc = (alloc_func)0; + d_stream.zfree = (free_func)0; + d_stream.opaque = (voidpf)0; + result = inflateInit(&d_stream); + if (result != Z_OK) { + printf("inflateInit() failed. Result: %d\n", result); + return(-1); + } + + d_stream.next_in = (Bytef *)src; + d_stream.avail_in = slen; + n = 0; + dst = NULL; + do { + n++; + dst = (unsigned char *)realloc(dst, n * 1000); + d_stream.next_out = (Bytef *)&dst[(n - 1) * 1000]; + d_stream.avail_out = 1000; + result = inflate(&d_stream, Z_NO_FLUSH); + if ((result != Z_OK) && (result != Z_STREAM_END)) { + printf("Zlib decompression failed. Result: %d\n", result); + return(-1); + } + } while ((d_stream.avail_out == 0) && (d_stream.avail_in != 0) && + (result != Z_STREAM_END)); + + dstsize = d_stream.total_out; + inflateEnd(&d_stream); + + *_dst = (unsigned char *)realloc(dst, dstsize); + + return dstsize; +} +#endif + /***************************************************************************** * Open: initialize and create stuff *****************************************************************************/ @@ -175,6 +242,7 @@ static int Open( vlc_object_t *p_this ) playlist_t *p_playlist; + p_sys->i_timeout = config_GetInt(p_intf,"sap-timeout"); p_sys->fd[0] = -1; p_sys->fd[1] = -1; if( config_GetInt( p_intf, "sap-ipv4" ) ) @@ -196,7 +264,7 @@ static int Open( vlc_object_t *p_this ) sock.i_ttl = 0; p_intf->p_private = (void*) &sock; - p_network = module_Need( p_intf, "network", "ipv4" ); + p_network = module_Need( p_intf, "network", "ipv4", VLC_TRUE ); if( p_network ) { p_sys->fd[0] = sock.i_handle; @@ -220,7 +288,8 @@ static int Open( vlc_object_t *p_this ) { psz_scope = strdup( "8" ); } - snprintf( psz_address, 100, "[%s%c%s]",IPV6_ADDR_1, psz_scope[0], IPV6_ADDR_2 ); + snprintf( psz_address, 100, "[%s%c%s]",IPV6_ADDR_1, + psz_scope[0], IPV6_ADDR_2 ); free( psz_scope ); sock.i_type = NETWORK_UDP; @@ -231,7 +300,7 @@ static int Open( vlc_object_t *p_this ) sock.i_ttl = 0; p_intf->p_private = (void*) &sock; - p_network = module_Need( p_intf, "network", "ipv6" ); + p_network = module_Need( p_intf, "network", "ipv6", VLC_TRUE ); if( p_network ) { p_sys->fd[1] = sock.i_handle; @@ -259,6 +328,9 @@ static int Open( vlc_object_t *p_this ) vlc_object_release( p_playlist ); } + p_sys->i_announces = 0; + p_sys->pp_announces = NULL; + p_intf->pf_run = Run; p_intf->p_sys = p_sys; @@ -272,6 +344,7 @@ static void Close( vlc_object_t *p_this ) { intf_thread_t *p_intf = (intf_thread_t*)p_this; intf_sys_t *p_sys = p_intf->p_sys; + int i; if( p_sys->fd[0] > 0 ) { @@ -282,6 +355,16 @@ static void Close( vlc_object_t *p_this ) close( p_sys->fd[1] ); } + for( i = 0 ; i< p_sys->i_announces ; i++ ) + { + if( p_sys->pp_announces[i]->psz_name ) + free( p_sys->pp_announces[i]->psz_name ); + if( p_sys->pp_announces[i]->psz_uri ) + free( p_sys->pp_announces[i]->psz_uri ); + free( p_sys->pp_announces[i] ); + } + free( p_sys->pp_announces ); + free( p_sys ); } @@ -290,18 +373,69 @@ static void Close( vlc_object_t *p_this ) ***************************************************************************** * Listens to SAP packets, and sends them to packet_handle *****************************************************************************/ -#define MAX_SAP_BUFFER 2000 +#define MAX_SAP_BUFFER 5000 static void Run( intf_thread_t *p_intf ) { intf_sys_t *p_sys = p_intf->p_sys; uint8_t buffer[MAX_SAP_BUFFER + 1]; + uint8_t *p_end; /* read SAP packets */ while( !p_intf->b_die ) { + playlist_t *p_playlist= NULL; + int i; int i_read = NetRead( p_intf, p_sys->fd, buffer, MAX_SAP_BUFFER ); uint8_t *p_sdp; + int i_version; + int i_address_type; + int b_reserved; + int b_message_type; + int b_encrypted; + int b_compressed; + unsigned char *p_decompressed_buffer; + int i_decompressed_size; + + /* Check for items that need deletion */ + for( i = 0 ; i< p_intf->p_sys->i_announces ; i++ ) + { + struct sap_announce_t *p_announce; + mtime_t i_timeout = (mtime_t)1000000*p_sys->i_timeout; + if( mdate() - p_intf->p_sys->pp_announces[i]->i_last > i_timeout ) + { + msg_Dbg(p_intf,"Time out for %s, deleting (%i/%i)", + p_intf->p_sys->pp_announces[i]->psz_name, + i , p_intf->p_sys->i_announces ); + + /* Remove the playlist item */ + p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, + FIND_ANYWHERE ); + if( p_playlist ) + { + int i_pos = playlist_GetPositionById( p_playlist, + p_intf->p_sys->pp_announces[i]->i_id ); + playlist_Delete( p_playlist, i_pos ); + } + + vlc_object_release( p_playlist ); + + /* Free the p_announce */ + p_announce = p_intf->p_sys->pp_announces[i]; + if( p_announce->psz_name ) + free( p_announce->psz_name ); + if( p_announce->psz_uri ) + free( p_announce->psz_uri ); + + /* Remove the sap_announce from the array */ + REMOVE_ELEM( p_intf->p_sys->pp_announces, + p_intf->p_sys->i_announces, + i ); + + free( p_announce ); + + } + } /* Minimum length is > 6 */ if( i_read <= 6 ) @@ -314,13 +448,57 @@ static void Run( intf_thread_t *p_intf ) } buffer[i_read] = '\0'; + p_end = &buffer[i_read]; /* Parse the SAP header */ + i_version = buffer[0] >> 5; + if( i_version != 1 ) + { + msg_Warn( p_intf, "strange sap version %d found", i_version ); + } + i_address_type = buffer[0] & 0x10; + b_reserved = buffer[0] & 0x08; + if( b_reserved != 0 ) + { + msg_Warn( p_intf, "reserved bit incorrectly set" ); + } + b_message_type = buffer[0] & 0x04; + if( b_message_type != 0 ) + { + msg_Warn( p_intf, "got session deletion packet" ); + } + b_encrypted = buffer[0] & 0x02; + if( b_encrypted ) + { + msg_Warn( p_intf, "encrypted packet" ); + } + b_compressed = buffer[0] & 0x01; p_sdp = &buffer[4]; - p_sdp += (buffer[0]&0x10) ? 16 : 4; - p_sdp += buffer[1]; - - while( p_sdp < &buffer[i_read-1] && *p_sdp != '\0' && p_sdp[0] != 'v' && p_sdp[1] != '=' ) + if( i_address_type == 0 ) /* ipv4 source address */ + { + p_sdp += 4; + } + else /* ipv6 source address */ + { + p_sdp += 16; + } + if( b_compressed ) + { +#ifdef HAVE_ZLIB_H + i_decompressed_size = do_decompress( p_sdp, &p_decompressed_buffer, i_read - ( p_sdp - buffer ) ); + if( i_decompressed_size > 0 && i_decompressed_size < MAX_SAP_BUFFER ) + { + memcpy( p_sdp, p_decompressed_buffer, i_decompressed_size ); + p_sdp[i_decompressed_size] = '\0'; + p_end = &p_sdp[i_decompressed_size]; + free( p_decompressed_buffer ); + } +#else + msg_Warn( p_intf, "Ignoring compressed sap packet" ); +#endif + } + p_sdp += buffer[1]; /* size of signature */ + while( p_sdp < p_end - 1 && *p_sdp != '\0' && p_sdp[0] != 'v' && p_sdp[1] != '=' ) { p_sdp++; } @@ -328,7 +506,8 @@ static void Run( intf_thread_t *p_intf ) { p_sdp++; } - if( p_sdp < &buffer[i_read] ) + + if( p_sdp < p_end ) { sess_descr_t *p_sd = parse_sdp( p_intf, p_sdp ); if( p_sd ) @@ -337,6 +516,11 @@ static void Run( intf_thread_t *p_intf ) free_sd ( p_sd ); } } + else + { + msg_Warn( p_intf, "ditching sap packet" ); + } + } } @@ -393,16 +577,28 @@ static void mfield_parse( char *psz_mfield, char **ppsz_proto, char **ppsz_port ) { char *psz_pos; + char *psz_media; if( psz_mfield ) { psz_pos = psz_mfield; + psz_media = psz_mfield; while( *psz_pos != '\0' && *psz_pos != ' ' ) { psz_pos++; } + if( *psz_pos != '\0' ) + { + *psz_pos = '\0'; + if( strcmp( psz_media, "video" ) && strcmp( psz_media, "audio" ) ) + { + *ppsz_proto = NULL; + *ppsz_port = NULL; + return; + } + } psz_pos++; *ppsz_port = psz_pos; - while( *psz_pos != '\0' && *psz_pos && *psz_pos !=' ' && *psz_pos!='/' ) + while( *psz_pos != '\0' && *psz_pos !=' ' && *psz_pos!='/' ) { psz_pos++; } @@ -445,38 +641,82 @@ static void mfield_parse( char *psz_mfield, char **ppsz_proto, static void sess_toitem( intf_thread_t * p_intf, sess_descr_t * p_sd ) { - playlist_item_t * p_item; - char *psz_uri, *psz_proto; + struct sap_announce_t *p_announce; + char *psz_uri, *psz_proto, *psz_item_uri; char *psz_port; char *psz_uri_default; - int i_count , i; + int i_count , i , i_pos , i_id = 0; vlc_bool_t b_http = VLC_FALSE; char *psz_http_path = NULL; - playlist_t *p_playlist; + playlist_t *p_playlist = NULL; + playlist_item_t *p_item; psz_uri_default = NULL; + if( p_sd->i_media > 1 ) + { + asprintf( &psz_uri, "sdp://%s", p_sd->psz_sdp ); + /* Check if we have already added the item */ + for( i = 0 ; i< p_intf->p_sys->i_announces ; i++ ) + { + if( !strcmp(p_intf->p_sys->pp_announces[i]->psz_uri, + psz_uri ) ) + { + p_intf->p_sys->pp_announces[i]->i_last = mdate(); + free(psz_uri); + return; + } + } + /* Add it to the playlist */ + p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, + FIND_ANYWHERE ); + i_id = playlist_Add( p_playlist, psz_uri, p_sd->psz_sessionname , + PLAYLIST_CHECK_INSERT, PLAYLIST_END ); + if( i_id != -1 ) + { + playlist_item_t *p_item = playlist_ItemGetById( p_playlist, i_id ); + playlist_ItemSetGroup( p_item, p_intf->p_sys->i_group ); + } + + /* Remember it */ + p_announce = (struct sap_announce_t *)malloc( + sizeof(struct sap_announce_t) ); + if( p_sd->psz_sessionname ) + { + p_announce->psz_name = strdup( p_sd->psz_sessionname ); + } + else + { + p_announce->psz_name = strdup( "" ); + } + if( psz_uri ) + { + p_announce->psz_uri = strdup( psz_uri ); + } + else + { + p_announce->psz_uri = strdup( "" ); + } + p_announce->i_id = i_id; + p_announce->i_last = mdate(); + + INSERT_ELEM( p_intf->p_sys->pp_announces, + p_intf->p_sys->i_announces, + p_intf->p_sys->i_announces, + p_announce ); + + vlc_object_release( p_playlist ); + free( psz_uri ); + return; + } + cfield_parse( p_sd->psz_connection, &psz_uri_default ); for( i_count = 0 ; i_count < p_sd->i_media ; i_count++ ) { - p_item = malloc( sizeof( playlist_item_t ) ); - p_item->psz_name = strdup( p_sd->psz_sessionname ); - p_item->psz_uri = NULL; - p_item->i_duration = -1; - p_item->ppsz_options= NULL; - p_item->i_options = 0; - - p_item->i_type = 0; - p_item->i_status = 0; - p_item->b_autodeletion = VLC_FALSE; - p_item->b_enabled = VLC_TRUE; - p_item->i_group = p_intf->p_sys->i_group; - p_item->psz_author = strdup( "" ); + int i_group = p_intf->p_sys->i_group; - psz_uri = NULL; - - /* Build what we have to put in p_item->psz_uri, with the m and - * c fields */ + /* Build what we have to put in psz_item_uri, with the m and + * c fields */ if( !p_sd->pp_media[i_count] ) { @@ -517,22 +757,47 @@ static void sess_toitem( intf_thread_t * p_intf, sess_descr_t * p_sd ) { psz_http_path = strdup( p_sd->pp_attributes[i]->psz_value ); } - } + if(!strcasecmp( p_sd->pp_attributes[i]->psz_field , "plgroup")) + { + int i_group_id; + p_playlist = + (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, + FIND_ANYWHERE ); + if( p_playlist == NULL ) + { + return; + } + i_group_id = playlist_GroupToId( p_playlist, + p_sd->pp_attributes[i]->psz_value); + if( i_group_id != 0 ) + { + i_group = i_group_id; + } + else + { + playlist_group_t *p_group = + playlist_CreateGroup( p_playlist, + p_sd->pp_attributes[i]->psz_value); + i_group = p_group->i_id; + } + vlc_object_release( p_playlist ); + } + } - /* Filling p_item->psz_uri */ + /* Filling psz_uri */ if( b_http == VLC_FALSE ) { - p_item->psz_uri = malloc( strlen( psz_proto ) + strlen( psz_uri ) + - strlen( psz_port ) + 7 ); + psz_item_uri = malloc( strlen( psz_proto ) + strlen( psz_uri ) + + strlen( psz_port ) + 7 ); if( ismult( psz_uri ) ) { - sprintf( p_item->psz_uri, "%s://@%s:%s", + sprintf( psz_item_uri, "%s://@%s:%s", psz_proto, psz_uri, psz_port ); } else { - sprintf( p_item->psz_uri, "%s://%s:%s", + sprintf( psz_item_uri, "%s://%s:%s", psz_proto, psz_uri, psz_port ); } } @@ -542,11 +807,16 @@ static void sess_toitem( intf_thread_t * p_intf, sess_descr_t * p_sd ) { psz_http_path = strdup( "/" ); } - - p_item->psz_uri = malloc( strlen( psz_proto ) + strlen( psz_uri ) + - strlen( psz_port ) + strlen(psz_http_path) + 5 ); - sprintf( p_item->psz_uri, "%s://%s:%s%s", psz_proto, - psz_uri, psz_port,psz_http_path ); + if( *psz_http_path == '/' ) + { + asprintf( &psz_item_uri, "%s://%s:%s%s", psz_proto, + psz_uri, psz_port,psz_http_path ); + } + else + { + asprintf( &psz_item_uri, "%s://%s:%s/%s", psz_proto, psz_uri, + psz_port, psz_http_path ); + } if( psz_http_path ) { @@ -554,10 +824,92 @@ static void sess_toitem( intf_thread_t * p_intf, sess_descr_t * p_sd ) } } - /* Enqueueing p_item in the playlist */ - p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE ); - playlist_AddItem ( p_playlist, p_item, PLAYLIST_CHECK_INSERT, PLAYLIST_END ); + /* Check if we already know this item */ + for( i = 0 ; i< p_intf->p_sys->i_announces ; i++ ) + { + if( !strcmp( p_intf->p_sys->pp_announces[i]->psz_uri, + psz_item_uri ) ) + { + p_intf->p_sys->pp_announces[i]->i_last = mdate(); + + /* Check if the name changed */ + if( strcmp( p_intf->p_sys->pp_announces[i]->psz_name, + p_sd->psz_sessionname ) ) + { + playlist_item_t *p_item; + p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, + FIND_ANYWHERE ); + + msg_Dbg(p_intf, "Name changed (%s -> %s) for %s", + p_intf->p_sys->pp_announces[i]->psz_name, + p_sd->psz_sessionname, + psz_item_uri ); + + p_item = playlist_ItemGetById( p_playlist, + p_intf->p_sys->pp_announces[i]->i_id ); + + /* Change the name in the item */ + if( p_item->input.psz_name ) + free( p_item->input.psz_name ); + p_item->input.psz_name = strdup( p_sd->psz_sessionname); + + /* Update the stored name */ + if( p_intf->p_sys->pp_announces[i]->psz_name ) + free( p_intf->p_sys->pp_announces[i]->psz_name ); + p_intf->p_sys->pp_announces[i]->psz_name = + strdup( p_sd->psz_sessionname ); + + vlc_object_release( p_playlist ); + } + free( psz_item_uri ); + return; + } + } + + /* Add the item in the playlist */ + p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, + FIND_ANYWHERE ); + i_id = playlist_Add ( p_playlist, psz_item_uri , + p_sd->psz_sessionname, + PLAYLIST_CHECK_INSERT, PLAYLIST_END ); + p_item = playlist_ItemGetById( p_playlist, i_id ); + if( p_item ) + { + vlc_mutex_lock( &p_item->input.lock ); + playlist_ItemSetGroup( p_item, i_group ); + vlc_mutex_unlock( &p_item->input.lock ); + } + + /* Then remember it */ + p_announce = (struct sap_announce_t *)malloc( + sizeof(struct sap_announce_t) ); + if( p_sd->psz_sessionname ) + { + p_announce->psz_name = strdup( p_sd->psz_sessionname ); + } + else + { + p_announce->psz_name = strdup( "" ); + } + if( psz_item_uri ) + { + p_announce->psz_uri = strdup( psz_item_uri ); + } + else + { + p_announce->psz_uri = strdup( "" ); + } + p_announce->i_id = i_id; + + p_announce->i_last = mdate(); + vlc_object_release( p_playlist ); + + INSERT_ELEM( p_intf->p_sys->pp_announces, + p_intf->p_sys->i_announces, + p_intf->p_sys->i_announces, + p_announce ); + free( psz_item_uri ); } } @@ -580,6 +932,8 @@ static sess_descr_t * parse_sdp( intf_thread_t * p_intf, char *p_packet ) sd = malloc( sizeof( sess_descr_t ) ); sd->psz_sessionname = NULL; sd->psz_connection = NULL; + sd->psz_sdp = strdup( p_packet ); + sd->i_media = 0; sd->pp_media = NULL; sd->i_attributes = 0; @@ -599,6 +953,10 @@ static sess_descr_t * parse_sdp( intf_thread_t * p_intf, char *p_packet ) { psz_end = p_packet + strlen( p_packet ); } + if( psz_end > p_packet && *(psz_end - 1 ) == '\r' ) + { + psz_end--; + } if( psz_end <= p_packet ) { @@ -687,16 +1045,19 @@ static void free_sd( sess_descr_t * p_sd ) FREE( p_sd->psz_sessionname ); FREE( p_sd->psz_connection ); + FREE( p_sd->psz_sdp ); for( i = 0; i < p_sd->i_media ; i++ ) { FREE( p_sd->pp_media[i]->psz_medianame ); FREE( p_sd->pp_media[i]->psz_mediaconnection ); + FREE( p_sd->pp_media[i] ); } for( i = 0; i < p_sd->i_attributes ; i++ ) { FREE( p_sd->pp_attributes[i]->psz_field ); FREE( p_sd->pp_attributes[i]->psz_value ); + FREE( p_sd->pp_attributes[i] ); } FREE( p_sd->pp_attributes ); FREE( p_sd->pp_media ); @@ -736,7 +1097,7 @@ static int ismult( char *psz_uri ) * Read: read on a file descriptor, checking b_die periodically ***************************************************************************** * Taken from udp.c - ******************************************************************************/ + *****************************************************************************/ static ssize_t NetRead( intf_thread_t *p_intf, int fd[2], uint8_t *p_buffer, int i_len ) { @@ -778,4 +1139,3 @@ static ssize_t NetRead( intf_thread_t *p_intf, return 0; #endif } -