1 /*****************************************************************************
2 * network.c: functions to read from the network
4 *****************************************************************************
5 * Copyright (C) 1999, 2000 VideoLAN
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
19 * You should have received a copy of the GNU General Public
20 * License along with this program; if not, write to the
21 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 * Boston, MA 02111-1307, USA.
23 *****************************************************************************/
25 /*****************************************************************************
27 *****************************************************************************/
28 #include <sys/types.h> /* on BSD, uio.h needs types.h */
29 #include <sys/uio.h> /* "input.h" */
30 #include <string.h> /* strerror() */
31 #include <unistd.h> /* close() */
32 #include <errno.h> /* errno */
33 #include <sys/time.h> /* "input_network.h" */
36 #include <sys/socket.h> /* struct sockaddr */
39 #include <netdb.h> /* servent, getservbyname(), hostent, gethostbyname() */
40 #include <netinet/in.h> /* sockaddr_in, htons(), htonl() */
49 #include "input_network.h"
50 #include "input_vlan.h"
55 /*****************************************************************************
56 * input_NetworkOpen: initialize a network stream
57 *****************************************************************************/
58 int input_NetworkOpen( input_thread_t *p_input )
61 struct sockaddr_in sa_in;
62 char psz_hostname[INPUT_MAX_SOURCE_LENGTH];
64 /* First and foremost, in the VLAN method, join the desired VLAN. */
65 if( p_input->i_method == INPUT_METHOD_TS_VLAN_BCAST )
67 if( input_VlanJoin( p_input->i_vlan ) )
69 intf_ErrMsg("error: can't join vlan %d\n", p_input->i_vlan);
74 /* Open a SOCK_DGRAM (UDP) socket, in the AF_INET domain, automatic (0)
76 if( (p_input->i_handle = socket( AF_INET, SOCK_DGRAM, 0 )) == (-1) )
78 intf_ErrMsg("error: can't create socket (%s)\n", strerror(errno));
83 * Set up the options of the socket
86 /* Set SO_REUSEADDR option which allows to re-bind() a busy port */
88 if( setsockopt( p_input->i_handle,
92 sizeof( i_socket_option ) ) == (-1) )
94 intf_ErrMsg("error: can't configure socket (SO_REUSEADDR: %s)\n", strerror(errno));
95 close( p_input->i_handle );
99 /* Increase the receive buffer size to 1/2MB (8Mb/s during 1/2s) to avoid
100 * packet loss caused by scheduling problems */
101 i_socket_option = 524288;
102 if( setsockopt( p_input->i_handle,
106 sizeof( i_socket_option ) ) == (-1) )
108 intf_ErrMsg("error: can't configure socket (SO_RCVBUF: %s)\n", strerror(errno));
109 close( p_input->i_handle );
117 /* Use default port if not specified */
118 if( p_input->i_port == 0 )
120 p_input->i_port = main_GetIntVariable( INPUT_PORT_VAR, INPUT_PORT_DEFAULT );
123 /* Find the address. */
124 switch( p_input->i_method )
126 case INPUT_METHOD_TS_BCAST:
127 case INPUT_METHOD_TS_VLAN_BCAST:
128 /* In that case, we have to bind with the broadcast address.
129 * broadcast addresses are very hard to find and depends on
130 * implementation, so we thought using a #define would be much
132 #ifdef INPUT_BCAST_ADDR
133 if( BuildInetAddr( &sa_in, INPUT_BCAST_ADDR, p_input->i_port ) == (-1) )
135 close( p_input->i_handle );
139 /* We bind with any address. Security problem ! */
140 if( BuildInetAddr( &sa_in, NULL, p_input->i_port ) == (-1) )
142 close( p_input->i_handle );
148 case INPUT_METHOD_TS_UCAST:
149 /* Unicast: bind with the local address. */
150 if( gethostname( psz_hostname, sizeof( psz_hostname ) ) == (-1) )
152 intf_ErrMsg("error: can't get hostname (%s)\n", strerror(errno));
153 close( p_input->i_handle );
156 if( BuildInetAddr( &sa_in, psz_hostname, p_input->i_port ) == (-1) )
158 close( p_input->i_handle );
163 case INPUT_METHOD_TS_MCAST:
164 /* Multicast: bind with 239.0.0.1. */
165 if( BuildInetAddr( &sa_in, "239.0.0.1", p_input->i_port ) == (-1) )
167 close( p_input->i_handle );
173 /* Effectively bind the socket. */
174 if( bind( p_input->i_handle, (struct sockaddr *) &sa_in, sizeof( sa_in ) ) < 0 )
176 intf_ErrMsg("error: can't bind socket (%s)\n", strerror(errno));
177 close( p_input->i_handle );
182 * Connect the socket to the remote server
185 /* Use default host if not specified */
186 if( p_input->psz_source == NULL )
188 p_input->psz_source = main_GetPszVariable( INPUT_SERVER_VAR, INPUT_SERVER_DEFAULT );
191 if( BuildInetAddr( &sa_in, p_input->psz_source, htons(0) ) == (-1) )
193 close( p_input->i_handle );
197 /* Connect the socket. */
198 if( connect( p_input->i_handle, (struct sockaddr *) &sa_in,
199 sizeof( sa_in ) ) == (-1) )
201 intf_ErrMsg("error: can't connect socket\n" );
202 close( p_input->i_handle );
208 /*****************************************************************************
209 * input_NetworkRead: read a stream from the network
210 *****************************************************************************
211 * Wait for data during up to 1 second and then abort if none is arrived. The
212 * number of bytes read is returned or -1 if an error occurs (so 0 is returned
214 * We don't have to make any test on presentation times, since we suppose
215 * the network server sends us data when we need it.
216 *****************************************************************************/
217 int input_NetworkRead( input_thread_t *p_input, const struct iovec *p_vector,
224 /* Watch the given fd to see when it has input */
226 FD_SET(p_input->i_handle, &rfds);
228 /* Wait up to 1 second */
232 i_rc = select(p_input->i_handle+1, &rfds, NULL, NULL, &tv);
236 /* Data were received before timeout */
237 i_rc = readv( p_input->i_handle, p_vector, i_count );
243 /*****************************************************************************
244 * input_NetworkClose: close a network stream
245 *****************************************************************************/
246 void input_NetworkClose( input_thread_t *p_input )
248 /* Close local socket. */
249 if( p_input->i_handle )
251 close( p_input->i_handle );
254 /* Leave vlan if required */
255 if( p_input->i_method == INPUT_METHOD_TS_VLAN_BCAST )
257 input_VlanLeave( p_input->i_vlan );