Bug Summary

File:udp.c
Location:line 384, column 9
Description:Function call argument is an uninitialized value

Annotated Source Code

1/*****************************************************************************
2 * udp.c: UDP input for DVBlast
3 *****************************************************************************
4 * Copyright (C) 2009 VideoLAN
5 *
6 * Authors: Christophe Massiot <massiot@via.ecp.fr>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 *****************************************************************************/
22
23#include <stdlib.h>
24#include <stdio.h>
25#include <unistd.h>
26#include <stdint.h>
27#include <stdbool.h>
28#include <string.h>
29#include <sys/types.h>
30#include <sys/stat.h>
31#include <fcntl.h>
32#include <sys/uio.h>
33#include <sys/poll.h>
34#include <sys/ioctl.h>
35#include <sys/socket.h>
36#include <netinet/in.h>
37#include <net/if.h>
38#include <arpa/inet.h>
39#include <errno(*__errno_location ()).h>
40
41#include <bitstream/common.h>
42#include <bitstream/ietf/rtp.h>
43
44#include "dvblast.h"
45
46/*****************************************************************************
47 * Local declarations
48 *****************************************************************************/
49#define UDP_LOCK_TIMEOUT5000000 5000000 /* 5 s */
50
51static int i_handle;
52static bool_Bool b_udp = false0;
53static int i_block_cnt;
54static uint8_t pi_ssrc[4] = { 0, 0, 0, 0 };
55static uint16_t i_seqnum = 0;
56static mtime_t i_last_packet = 0;
57
58/*****************************************************************************
59 * udp_Open
60 *****************************************************************************/
61void udp_Open( void )
62{
63 int i_family;
64 struct addrinfo *p_connect_ai = NULL((void*)0), *p_bind_ai;
65 int i_if_index = 0;
66 in_addr_t i_if_addr = INADDR_ANY((in_addr_t) 0x00000000);
67 int i_mtu = 0;
68 char *psz_ifname = NULL((void*)0);
69
70 char *psz_bind, *psz_string = strdup( psz_udp_src )(__extension__ (__builtin_constant_p (psz_udp_src) &&
((size_t)(const void *)((psz_udp_src) + 1) - (size_t)(const void
*)(psz_udp_src) == 1) ? (((const char *) (psz_udp_src))[0] ==
'\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len
= strlen (psz_udp_src) + 1; char *__retval = (char *) malloc
(__len); if (__retval != ((void*)0)) __retval = (char *) memcpy
(__retval, psz_udp_src, __len); __retval; })) : __strdup (psz_udp_src
)))
;
71 char *psz_save = psz_string;
72 int i = 1;
73
74 /* Parse configuration. */
75
76 if ( (psz_bind = strchr( psz_string, '@' )(__extension__ (__builtin_constant_p ('@') && !__builtin_constant_p
(psz_string) && ('@') == '\0' ? (char *) __rawmemchr
(psz_string, '@') : __builtin_strchr (psz_string, '@')))
) != NULL((void*)0) )
77 {
78 *psz_bind++ = '\0';
79 p_connect_ai = ParseNodeService( psz_string, NULL((void*)0), 0 );
80 }
81 else
82 psz_bind = psz_string;
83
84 p_bind_ai = ParseNodeService( psz_bind, &psz_string, DEFAULT_PORT3001 );
85 if ( p_bind_ai == NULL((void*)0) )
86 {
87 msg_Err( NULL((void*)0), "couldn't parse %s", psz_bind );
88 exit(EXIT_FAILURE1);
89 }
90 i_family = p_bind_ai->ai_family;
91
92 if ( p_connect_ai != NULL((void*)0) && p_connect_ai->ai_family != i_family )
93 {
94 msg_Warn( NULL((void*)0), "invalid connect address" );
95 freeaddrinfo( p_connect_ai );
96 p_connect_ai = NULL((void*)0);
97 }
98
99 while ( (psz_string = strchr( psz_string, '/' )(__extension__ (__builtin_constant_p ('/') && !__builtin_constant_p
(psz_string) && ('/') == '\0' ? (char *) __rawmemchr
(psz_string, '/') : __builtin_strchr (psz_string, '/')))
) != NULL((void*)0) )
100 {
101 *psz_string++ = '\0';
102
103#define IS_OPTION( option ) (!strncasecmp( psz_string, option, strlen(option) ))
104#define ARG_OPTION( option ) (psz_string + strlen(option))
105
106 if ( IS_OPTION("udp") )
107 b_udp = true1;
108 else if ( IS_OPTION("mtu=") )
109 i_mtu = strtol( ARG_OPTION("mtu="), NULL((void*)0), 0 );
110 else if ( IS_OPTION("ifindex=") )
111 i_if_index = strtol( ARG_OPTION("ifindex="), NULL((void*)0), 0 );
112 else if ( IS_OPTION("ifaddr=") ) {
113 char *option = config_stropt( ARG_OPTION("ifaddr=") );
114 i_if_addr = inet_addr( option );
115 free( option );
116 }
117 else if ( IS_OPTION("ifname=") )
118 {
119 psz_ifname = config_stropt( ARG_OPTION("ifname=") );
120 if (strlen(psz_ifname) >= IFNAMSIZ16) {
121 psz_ifname[IFNAMSIZ16-1] = '\0';
122 }
123 } else
124 msg_Warn( NULL((void*)0), "unrecognized option %s", psz_string );
125
126#undef IS_OPTION
127#undef ARG_OPTION
128 }
129
130 if ( !i_mtu )
131 i_mtu = i_family == AF_INET610 ? DEFAULT_IPV6_MTU1280 : DEFAULT_IPV4_MTU1500;
132 i_block_cnt = (i_mtu - (b_udp ? 0 : RTP_HEADER_SIZE12)) / TS_SIZE188;
133
134
135 /* Do stuff. */
136
137 if ( (i_handle = socket( i_family, SOCK_DGRAMSOCK_DGRAM, IPPROTO_UDPIPPROTO_UDP )) < 0 )
138 {
139 msg_Err( NULL((void*)0), "couldn't create socket (%s)", strerror(errno(*__errno_location ())) );
140 exit(EXIT_FAILURE1);
141 }
142
143 setsockopt( i_handle, SOL_SOCKET1, SO_REUSEADDR2, (void *) &i, sizeof( i ) );
144
145 /* Increase the receive buffer size to 1/2MB (8Mb/s during 1/2s) to avoid
146 * packet loss caused by scheduling problems */
147 i = 0x80000;
148
149 setsockopt( i_handle, SOL_SOCKET1, SO_RCVBUF8, (void *) &i, sizeof( i ) );
150
151 if ( bind( i_handle, p_bind_ai->ai_addr, p_bind_ai->ai_addrlen ) < 0 )
152 {
153 msg_Err( NULL((void*)0), "couldn't bind (%s)", strerror(errno(*__errno_location ())) );
154 close( i_handle );
155 exit(EXIT_FAILURE1);
156 }
157
158 if ( p_connect_ai != NULL((void*)0) )
159 {
160 uint16_t i_port;
161 if ( i_family == AF_INET610 )
162 i_port = ((struct sockaddr_in6 *)p_connect_ai->ai_addr)->sin6_port;
163 else
164 i_port = ((struct sockaddr_in *)p_connect_ai->ai_addr)->sin_port;
165
166 if ( i_port != 0 && connect( i_handle, p_connect_ai->ai_addr,
167 p_connect_ai->ai_addrlen ) < 0 )
168 msg_Warn( NULL((void*)0), "couldn't connect socket (%s)", strerror(errno(*__errno_location ())) );
169 }
170
171 /* Join the multicast group if the socket is a multicast address */
172 if ( i_family == AF_INET610 )
173 {
174 struct sockaddr_in6 *p_addr =
175 (struct sockaddr_in6 *)p_bind_ai->ai_addr;
176 if ( IN6_IS_ADDR_MULTICAST( &p_addr->sin6_addr )(((const uint8_t *) (&p_addr->sin6_addr))[0] == 0xff) )
177 {
178 struct ipv6_mreq imr;
179 imr.ipv6mr_multiaddr = p_addr->sin6_addr;
180 imr.ipv6mr_interface = i_if_index;
181 if ( i_if_addr != INADDR_ANY((in_addr_t) 0x00000000) )
182 msg_Warn( NULL((void*)0), "ignoring ifaddr option in IPv6" );
183
184 if ( setsockopt( i_handle, IPPROTO_IPV6IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP20,
185 (char *)&imr, sizeof(struct ipv6_mreq) ) < 0 )
186 msg_Warn( NULL((void*)0), "couldn't join multicast group (%s)",
187 strerror(errno(*__errno_location ())) );
188 }
189 }
190 else
191 {
192 struct sockaddr_in *p_addr =
193 (struct sockaddr_in *)p_bind_ai->ai_addr;
194 if ( IN_MULTICAST( ntohl(p_addr->sin_addr.s_addr))((((in_addr_t)((__extension__ ({ unsigned int __v, __x = (p_addr
->sin_addr.s_addr); if (__builtin_constant_p (__x)) __v = (
(((__x) & 0xff000000) >> 24) | (((__x) & 0x00ff0000
) >> 8) | (((__x) & 0x0000ff00) << 8) | (((__x
) & 0x000000ff) << 24)); else __asm__ ("bswap %0" :
"=r" (__v) : "0" (__x)); __v; })))) & 0xf0000000) == 0xe0000000
)
)
195 {
196 if ( p_connect_ai != NULL((void*)0) )
197 {
198#ifndef IP_ADD_SOURCE_MEMBERSHIP39
199 msg_Err( NULL((void*)0), "IP_ADD_SOURCE_MEMBERSHIP is unsupported." );
200#else
201 /* Source-specific multicast */
202 struct sockaddr *p_src = p_connect_ai->ai_addr;
203 struct ip_mreq_source imr;
204 imr.imr_multiaddr = p_addr->sin_addr;
205 imr.imr_interface.s_addr = i_if_addr;
206 imr.imr_sourceaddr = ((struct sockaddr_in *)p_src)->sin_addr;
207 if ( i_if_index )
208 msg_Warn( NULL((void*)0), "ignoring ifindex option in SSM" );
209
210 if ( setsockopt( i_handle, IPPROTO_IPIPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP39,
211 (char *)&imr, sizeof(struct ip_mreq_source) ) < 0 )
212 msg_Warn( NULL((void*)0), "couldn't join multicast group (%s)",
213 strerror(errno(*__errno_location ())) );
214#endif
215 }
216 else if ( i_if_index )
217 {
218 /* Linux-specific interface-bound multicast */
219 struct ip_mreqn imr;
220 imr.imr_multiaddr = p_addr->sin_addr;
221#if defined(__linux__1)
222 imr.imr_address.s_addr = i_if_addr;
223 imr.imr_ifindex = i_if_index;
224#endif
225
226 if ( setsockopt( i_handle, IPPROTO_IPIPPROTO_IP, IP_ADD_MEMBERSHIP35,
227 (char *)&imr, sizeof(struct ip_mreqn) ) < 0 )
228 msg_Warn( NULL((void*)0), "couldn't join multicast group (%s)",
229 strerror(errno(*__errno_location ())) );
230 }
231 else
232 {
233 /* Regular multicast */
234 struct ip_mreq imr;
235 imr.imr_multiaddr = p_addr->sin_addr;
236 imr.imr_interface.s_addr = i_if_addr;
237
238 if ( setsockopt( i_handle, IPPROTO_IPIPPROTO_IP, IP_ADD_MEMBERSHIP35,
239 (char *)&imr, sizeof(struct ip_mreq) ) == -1 )
240 msg_Warn( NULL((void*)0), "couldn't join multicast group (%s)",
241 strerror(errno(*__errno_location ())) );
242 }
243#ifdef SO_BINDTODEVICE25
244 if (psz_ifname) {
245 if ( setsockopt( i_handle, SOL_SOCKET1, SO_BINDTODEVICE25,
246 psz_ifname, strlen(psz_ifname)+1 ) < 0 ) {
247 msg_Err( NULL((void*)0), "couldn't bind to device %s (%s)",
248 psz_ifname, strerror(errno(*__errno_location ())) );
249 }
250 free(psz_ifname);
251 psz_ifname = NULL((void*)0);
252 }
253#endif
254 }
255 }
256
257 freeaddrinfo( p_bind_ai );
258 if ( p_connect_ai != NULL((void*)0) )
259 freeaddrinfo( p_connect_ai );
260 free( psz_save );
261
262 msg_Dbg( NULL((void*)0), "binding socket to %s", psz_udp_src );
263}
264
265/*****************************************************************************
266 * udp_Read
267 *****************************************************************************/
268block_t *udp_Read( mtime_t i_poll_timeout )
269{
270 struct pollfd pfd[2];
271 int i_ret, i_nb_fd = 1;
272
273 pfd[0].fd = i_handle;
274 pfd[0].events = POLLIN0x001;
275 if ( i_comm_fd != -1 )
1
Taking false branch
276 {
277 pfd[1].fd = i_comm_fd;
278 pfd[1].events = POLLIN0x001;
279 i_nb_fd++;
280 }
281
282 i_ret = poll( pfd, i_nb_fd, (i_poll_timeout + 999) / 1000 );
283
284 i_wallclock = mdate();
285
286 if ( i_ret < 0 )
2
Assuming 'i_ret' is >= 0
3
Taking false branch
287 {
288 if( errno(*__errno_location ()) != EINTR4 )
289 msg_Err( NULL((void*)0), "couldn't poll from socket (%s)",
290 strerror(errno(*__errno_location ())) );
291 return NULL((void*)0);
292 }
293
294 if ( pfd[0].revents )
4
Taking true branch
295 {
296 struct iovec p_iov[i_block_cnt + 1];
297 block_t *p_ts, **pp_current = &p_ts;
298 int i_iov, i_block;
299 ssize_t i_len;
300 uint8_t p_rtp_hdr[RTP_HEADER_SIZE12];
301
302 if ( !i_last_packet )
5
Assuming 'i_last_packet' is not equal to 0
6
Taking false branch
303 {
304 switch (i_print_type) {
305 case PRINT_XML:
306 printf("<STATUS type=\"lock\" status=\"1\"/>\n");
307 break;
308 default:
309 printf("frontend has acquired lock\n" );
310 }
311 }
312 i_last_packet = i_wallclock;
313
314 if ( !b_udp )
7
Assuming 'b_udp' is not equal to 0
8
Taking false branch
315 {
316 /* FIXME : this is wrong if RTP header > 12 bytes */
317 p_iov[0].iov_base = p_rtp_hdr;
318 p_iov[0].iov_len = RTP_HEADER_SIZE12;
319 i_iov = 1;
320 }
321 else
322 i_iov = 0;
323
324 for ( i_block = 0; i_block < i_block_cnt; i_block++ )
9
Assuming 'i_block' is >= 'i_block_cnt'
10
Loop condition is false. Execution continues on line 332
325 {
326 *pp_current = block_New();
327 p_iov[i_iov].iov_base = (*pp_current)->p_ts;
328 p_iov[i_iov].iov_len = TS_SIZE188;
329 pp_current = &(*pp_current)->p_next;
330 i_iov++;
331 }
332 pp_current = &p_ts;
333
334 if ( (i_len = readv( i_handle, p_iov, i_iov )) < 0 )
11
Taking true branch
335 {
336 msg_Err( NULL((void*)0), "couldn't read from network (%s)", strerror(errno(*__errno_location ())) );
337 goto err;
12
Control jumps to line 384
338 }
339
340 if ( !b_udp )
341 {
342 uint8_t pi_new_ssrc[4];
343
344 if ( !rtp_check_hdr(p_rtp_hdr) )
345 msg_Warn( NULL((void*)0), "invalid RTP packet received" );
346 if ( rtp_get_type(p_rtp_hdr) != RTP_TYPE_TS33 )
347 msg_Warn( NULL((void*)0), "non-TS RTP packet received" );
348 rtp_get_ssrc(p_rtp_hdr, pi_new_ssrc);
349 if ( !memcmp( pi_ssrc, pi_new_ssrc, 4 * sizeof(uint8_t) ) )
350 {
351 if ( rtp_get_seqnum(p_rtp_hdr) != i_seqnum )
352 msg_Warn( NULL((void*)0), "RTP discontinuity" );
353 }
354 else
355 {
356 struct in_addr addr;
357 memcpy( &addr.s_addr, pi_new_ssrc, 4 * sizeof(uint8_t) );
358 msg_Dbg( NULL((void*)0), "new RTP source: %s", inet_ntoa( addr ) );
359 memcpy( pi_ssrc, pi_new_ssrc, 4 * sizeof(uint8_t) );
360 switch (i_print_type) {
361 case PRINT_XML:
362 printf("<STATUS type=\"source\" source=\"%s\"/>\n",
363 inet_ntoa( addr ));
364 break;
365 default:
366 printf("new RTP source: %s\n", inet_ntoa( addr ) );
367 }
368 }
369 i_seqnum = rtp_get_seqnum(p_rtp_hdr) + 1;
370
371 i_len -= RTP_HEADER_SIZE12;
372 }
373
374 i_len /= TS_SIZE188;
375
376 while ( i_len && *pp_current )
377 {
378 pp_current = &(*pp_current)->p_next;
379 i_len--;
380 }
381
382 i_wallclock = mdate();
383err:
384 block_DeleteChain( *pp_current );
13
Function call argument is an uninitialized value
385 *pp_current = NULL((void*)0);
386
387 return p_ts;
388 }
389 else if ( i_last_packet && i_last_packet + UDP_LOCK_TIMEOUT5000000 < i_wallclock )
390 {
391 switch (i_print_type) {
392 case PRINT_XML:
393 printf("<STATUS type=\"lock\" status=\"0\"/>\n");
394 break;
395 default:
396 printf("frontend has lost lock\n" );
397 }
398 i_last_packet = 0;
399 }
400
401 if ( i_comm_fd != -1 && pfd[1].revents )
402 comm_Read();
403
404 return NULL((void*)0);
405}
406
407/* From now on these are just stubs */
408
409/*****************************************************************************
410 * udp_SetFilter
411 *****************************************************************************/
412int udp_SetFilter( uint16_t i_pid )
413{
414 return -1;
415}
416
417/*****************************************************************************
418 * udp_UnsetFilter: normally never called
419 *****************************************************************************/
420void udp_UnsetFilter( int i_fd, uint16_t i_pid )
421{
422}
423
424/*****************************************************************************
425 * udp_Reset:
426 *****************************************************************************/
427void udp_Reset( void )
428{
429}
430