X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fservices_discovery%2Fsap.c;h=392d213671afc573508fabc8d5d22486ba2fcd81;hb=56220f86120b3d7b7d8c7b2957befede19f669b6;hp=c8bac82b2c08d9c61f82b85d96bd950e2d9026af;hpb=aea7f120cac105e66b89443a2e50e3b68117732f;p=vlc diff --git a/modules/services_discovery/sap.c b/modules/services_discovery/sap.c index c8bac82b2c..392d213671 100644 --- a/modules/services_discovery/sap.c +++ b/modules/services_discovery/sap.c @@ -30,6 +30,7 @@ # include "config.h" #endif +#define VLC_MODULE_LICENSE VLC_LICENSE_GPL_2_PLUS #include #include #include @@ -40,9 +41,8 @@ #include #include -#ifdef HAVE_UNISTD_H -# include -#endif +#include +#include #ifdef HAVE_ARPA_INET_H # include #endif @@ -54,7 +54,7 @@ # include #endif -#ifndef WIN32 +#ifndef _WIN32 # include #endif @@ -172,6 +172,9 @@ struct sdp_t /* s= field */ char *psz_sessionname; + /* i= field */ + char *psz_sessioninfo; + /* old cruft */ /* "computed" URI */ char *psz_uri; @@ -348,7 +351,7 @@ static int OpenDemux( vlc_object_t *p_this ) for( i_len = 0, psz_sdp = NULL; i_len < 65536; ) { const int i_read_max = 1024; - char *psz_sdp_new = realloc( psz_sdp, i_len + i_read_max ); + char *psz_sdp_new = realloc( psz_sdp, i_len + i_read_max + 1 ); size_t i_read; if( psz_sdp_new == NULL ) { @@ -470,7 +473,7 @@ static void *Run( void *data ) InitSocket( p_sd, SAP_V4_LINK_ADDRESS, SAP_PORT ); char psz_address[NI_MAXNUMERICHOST] = "ff02::2:7ffe%"; -#ifndef WIN32 +#ifndef _WIN32 struct if_nameindex *l = if_nameindex (); if (l != NULL) { @@ -554,7 +557,8 @@ static void *Run( void *data ) i_read = net_Read (p_sd, ufd[i].fd, NULL, p_buffer, MAX_SAP_BUFFER, false); if (i_read < 0) - msg_Warn (p_sd, "receive error: %m"); + msg_Warn (p_sd, "receive error: %s", + vlc_strerror_c(errno)); if (i_read > 6) { /* Parse the packet */ @@ -567,7 +571,7 @@ static void *Run( void *data ) mtime_t now = mdate(); - /* A 1 hour timeout correspong to the RFC Implicit timeout. + /* A 1 hour timeout correspond to the RFC Implicit timeout. * This timeout is tuned in the following loop. */ timeout = 1000 * 60 * 60; @@ -578,10 +582,10 @@ static void *Run( void *data ) sap_announce_t * p_announce = p_sd->p_sys->pp_announces[i]; mtime_t i_last_period = now - p_announce->i_last; - /* Remove the annoucement, if the last announcement was 1 hour ago - * or if the last packet emitted was 3 times the average time + /* Remove the announcement, if the last announcement was 1 hour ago + * or if the last packet emitted was 10 times the average time * between two packets */ - if( ( p_announce->i_period_trust > 5 && i_last_period > 3 * p_announce->i_period ) || + if( ( p_announce->i_period_trust > 5 && i_last_period > 10 * p_announce->i_period ) || i_last_period > i_timeout ) { RemoveAnnounce( p_sd, p_announce ); @@ -590,7 +594,7 @@ static void *Run( void *data ) { /* Compute next timeout */ if( p_announce->i_period_trust > 5 ) - timeout = min_int((3 * p_announce->i_period - i_last_period) / 1000, timeout); + timeout = min_int((10 * p_announce->i_period - i_last_period) / 1000, timeout); timeout = min_int((i_timeout - i_last_period)/1000, timeout); } } @@ -600,7 +604,7 @@ static void *Run( void *data ) else if( timeout < 200 ) timeout = 200; /* Don't wakeup too fast. */ } - assert (0); + vlc_assert_unreachable (); } /********************************************************************** @@ -747,12 +751,12 @@ static int ParseSAP( services_discovery_t *p_sd, const uint8_t *buf, if (strcmp (psz_sdp, "application/sdp")) { msg_Dbg (p_sd, "unsupported content type: %s", psz_sdp); - return VLC_EGENERIC; + goto error; } // skips content type if (len <= clen) - return VLC_EGENERIC; + goto error; len -= clen; psz_sdp += clen; @@ -762,7 +766,7 @@ static int ParseSAP( services_discovery_t *p_sd, const uint8_t *buf, p_sdp = ParseSDP( VLC_OBJECT(p_sd), psz_sdp ); if( p_sdp == NULL ) - return VLC_EGENERIC; + goto error; p_sdp->psz_sdp = psz_sdp; @@ -782,7 +786,7 @@ static int ParseSAP( services_discovery_t *p_sd, const uint8_t *buf, if( p_sdp->psz_uri == NULL ) { FreeSDP( p_sdp ); - return VLC_EGENERIC; + goto error; } for( i = 0 ; i< p_sd->p_sys->i_announces ; i++ ) @@ -795,7 +799,7 @@ static int ParseSAP( services_discovery_t *p_sd, const uint8_t *buf, { /* We don't support delete announcement as they can easily * Be used to highjack an announcement by a third party. - * Intead we cleverly implement Implicit Announcement removal. + * Instead we cleverly implement Implicit Announcement removal. * * if( b_need_delete ) * RemoveAnnounce( p_sd, p_sd->p_sys->pp_announces[i]); @@ -811,18 +815,22 @@ static int ParseSAP( services_discovery_t *p_sd, const uint8_t *buf, /* Compute the average period */ mtime_t now = mdate(); - p_announce->i_period = (p_announce->i_period + (now - p_announce->i_last)) / 2; + p_announce->i_period = ( p_announce->i_period * (p_announce->i_period_trust-1) + (now - p_announce->i_last) ) / p_announce->i_period_trust; p_announce->i_last = now; } - FreeSDP( p_sdp ); p_sdp = NULL; + FreeSDP( p_sdp ); + free (decomp); return VLC_SUCCESS; } } CreateAnnounce( p_sd, i_source, i_hash, p_sdp ); - FREENULL (decomp); + free (decomp); return VLC_SUCCESS; +error: + free (decomp); + return VLC_EGENERIC; } sap_announce_t *CreateAnnounce( services_discovery_t *p_sd, uint32_t *i_source, uint16_t i_hash, @@ -849,12 +857,19 @@ sap_announce_t *CreateAnnounce( services_discovery_t *p_sd, uint32_t *i_source, p_input = input_item_NewWithType( p_sap->p_sdp->psz_uri, p_sdp->psz_sessionname, 0, NULL, 0, -1, ITEM_TYPE_NET ); - p_sap->p_item = p_input; - if( !p_input ) + if( unlikely(p_input == NULL) ) { free( p_sap ); return NULL; } + p_sap->p_item = p_input; + + vlc_meta_t *p_meta = vlc_meta_New(); + if( likely(p_meta != NULL) ) + { + vlc_meta_Set( p_meta, vlc_meta_Description, p_sdp->psz_sessioninfo ); + p_input->p_meta = p_meta; + } if( p_sdp->rtcp_port ) { @@ -1245,7 +1260,7 @@ static sdp_t *ParseSDP (vlc_object_t *p_obj, const char *psz_sdp) { msg_Dbg (p_obj, "SDP origin not supported: %s", data); /* Or maybe out-of-range, but this looks suspicious */ - return NULL; + goto error; } EnsureUTF8 (p_sdp->orig_host); break; @@ -1269,9 +1284,20 @@ static sdp_t *ParseSDP (vlc_object_t *p_obj, const char *psz_sdp) } case 'I': + { expect = 'U'; + /* optional (and may be empty) */ if (cat == 'i') + { + assert (p_sdp->psz_sessioninfo == NULL); + p_sdp->psz_sessioninfo = strdup (data); + if (p_sdp->psz_sessioninfo == NULL) + goto error; + EnsureUTF8 (p_sdp->psz_sessioninfo); break; + } + } + case 'U': expect = 'E'; if (cat == 'u') @@ -1424,12 +1450,8 @@ static sdp_t *ParseSDP (vlc_object_t *p_obj, const char *psz_sdp) if (cat == 'm') goto media; - if (cat != 'm') - { - msg_Dbg (p_obj, "unexpected SDP line: 0x%02x", (int)cat); - goto error; - } - break; + msg_Dbg (p_obj, "unexpected SDP line: 0x%02x", (int)cat); + goto error; default: msg_Err (p_obj, "*** BUG in SDP parser! ***"); @@ -1509,6 +1531,7 @@ static int Decompress( const unsigned char *psz_src, unsigned char **_dst, int i static void FreeSDP( sdp_t *p_sdp ) { free( p_sdp->psz_sessionname ); + free( p_sdp->psz_sessioninfo ); free( p_sdp->psz_uri ); for (unsigned j = 0; j < p_sdp->mediac; j++)