Mercurial > mplayer.hg
annotate stream/tcp.c @ 22153:0cf24df5d97b
Revert part of commit r22170.
FFmpeg lavcodecs version is still
(or according to ffmpeg commit r7868, it's back to)
49.3.0, so global variables are not yet directly accessable (if ever).
author | iive |
---|---|
date | Wed, 07 Feb 2007 12:31:37 +0000 |
parents | 84f95595f31f |
children | 6b245d6e56a9 |
rev | line source |
---|---|
19542 | 1 /* |
2 * Network layer for MPlayer | |
3 * by Bertrand BAUDET <bertrand_baudet@yahoo.com> | |
4 * (C) 2001, MPlayer team. | |
5 */ | |
6 | |
7 #include <stdlib.h> | |
8 #include <string.h> | |
9 #include <unistd.h> | |
10 | |
11 #include <errno.h> | |
12 #include <ctype.h> | |
13 | |
14 #include <fcntl.h> | |
15 #include <sys/time.h> | |
16 #include <sys/types.h> | |
17 | |
18 #include "config.h" | |
19 | |
20 #include "mp_msg.h" | |
21 #include "help_mp.h" | |
22142
84f95595f31f
Fix a few gcc warnings, approved by Diego and Reimar.
rathann
parents:
22114
diff
changeset
|
22 #include "input/input.h" |
19542 | 23 |
24 #ifndef HAVE_WINSOCK2 | |
25 #include <netdb.h> | |
26 #include <netinet/in.h> | |
27 #include <sys/socket.h> | |
28 #include <arpa/inet.h> | |
29 #define closesocket close | |
30 #else | |
31 #include <winsock2.h> | |
32 #include <ws2tcpip.h> | |
33 #endif | |
34 | |
35 #include "tcp.h" | |
36 | |
37 /* IPv6 options */ | |
38 int network_prefer_ipv4 = 0; | |
39 | |
40 // Converts an address family constant to a string | |
41 | |
42 const char *af2String(int af) { | |
43 switch (af) { | |
44 case AF_INET: return "AF_INET"; | |
45 | |
46 #ifdef HAVE_AF_INET6 | |
47 case AF_INET6: return "AF_INET6"; | |
48 #endif | |
49 default: return "Unknown address family!"; | |
50 } | |
51 } | |
52 | |
53 | |
54 | |
55 // Connect to a server using a TCP connection, with specified address family | |
56 // return -2 for fatal error, like unable to resolve name, connection timeout... | |
57 // return -1 is unable to connect to a particular port | |
58 | |
59 int | |
60 connect2Server_with_af(char *host, int port, int af,int verb) { | |
61 int socket_server_fd; | |
62 int err; | |
63 socklen_t err_len; | |
64 int ret,count = 0; | |
65 fd_set set; | |
66 struct timeval tv; | |
67 union { | |
68 struct sockaddr_in four; | |
69 #ifdef HAVE_AF_INET6 | |
70 struct sockaddr_in6 six; | |
71 #endif | |
72 } server_address; | |
73 size_t server_address_size; | |
74 void *our_s_addr; // Pointer to sin_addr or sin6_addr | |
75 struct hostent *hp=NULL; | |
76 char buf[255]; | |
77 | |
78 #ifdef HAVE_WINSOCK2 | |
79 u_long val; | |
80 #endif | |
81 | |
82 socket_server_fd = socket(af, SOCK_STREAM, 0); | |
83 | |
84 | |
85 if( socket_server_fd==-1 ) { | |
86 // mp_msg(MSGT_NETWORK,MSGL_ERR,"Failed to create %s socket:\n", af2String(af)); | |
19543
e053647fbeec
Cosmetics: recommit patch changing return values to defines
reimar
parents:
19542
diff
changeset
|
87 return TCP_ERROR_FATAL; |
19542 | 88 } |
89 | |
22114 | 90 #if defined(SO_RCVTIMEO) && defined(SO_SNDTIMEO) |
22113
50c9dc00154d
Add timeout to tcp connections, avoid hanging forever.
rtogni
parents:
19543
diff
changeset
|
91 tv.tv_sec = 10; |
50c9dc00154d
Add timeout to tcp connections, avoid hanging forever.
rtogni
parents:
19543
diff
changeset
|
92 tv.tv_usec = 0; |
50c9dc00154d
Add timeout to tcp connections, avoid hanging forever.
rtogni
parents:
19543
diff
changeset
|
93 setsockopt(socket_server_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); |
50c9dc00154d
Add timeout to tcp connections, avoid hanging forever.
rtogni
parents:
19543
diff
changeset
|
94 setsockopt(socket_server_fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); |
50c9dc00154d
Add timeout to tcp connections, avoid hanging forever.
rtogni
parents:
19543
diff
changeset
|
95 #endif |
50c9dc00154d
Add timeout to tcp connections, avoid hanging forever.
rtogni
parents:
19543
diff
changeset
|
96 |
19542 | 97 switch (af) { |
98 case AF_INET: our_s_addr = (void *) &server_address.four.sin_addr; break; | |
99 #ifdef HAVE_AF_INET6 | |
100 case AF_INET6: our_s_addr = (void *) &server_address.six.sin6_addr; break; | |
101 #endif | |
102 default: | |
103 mp_msg(MSGT_NETWORK,MSGL_ERR, MSGTR_MPDEMUX_NW_UnknownAF, af); | |
19543
e053647fbeec
Cosmetics: recommit patch changing return values to defines
reimar
parents:
19542
diff
changeset
|
104 return TCP_ERROR_FATAL; |
19542 | 105 } |
106 | |
107 | |
108 memset(&server_address, 0, sizeof(server_address)); | |
109 | |
110 #ifndef HAVE_WINSOCK2 | |
111 #ifdef USE_ATON | |
112 if (inet_aton(host, our_s_addr)!=1) | |
113 #else | |
114 if (inet_pton(af, host, our_s_addr)!=1) | |
115 #endif | |
116 #else | |
117 if ( inet_addr(host)==INADDR_NONE ) | |
118 #endif | |
119 { | |
120 if(verb) mp_msg(MSGT_NETWORK,MSGL_STATUS,MSGTR_MPDEMUX_NW_ResolvingHostForAF, host, af2String(af)); | |
121 | |
122 #ifdef HAVE_GETHOSTBYNAME2 | |
123 hp=(struct hostent*)gethostbyname2( host, af ); | |
124 #else | |
125 hp=(struct hostent*)gethostbyname( host ); | |
126 #endif | |
127 if( hp==NULL ) { | |
128 if(verb) mp_msg(MSGT_NETWORK,MSGL_ERR,MSGTR_MPDEMUX_NW_CantResolv, af2String(af), host); | |
19543
e053647fbeec
Cosmetics: recommit patch changing return values to defines
reimar
parents:
19542
diff
changeset
|
129 return TCP_ERROR_FATAL; |
19542 | 130 } |
131 | |
132 memcpy( our_s_addr, (void*)hp->h_addr_list[0], hp->h_length ); | |
133 } | |
134 #ifdef HAVE_WINSOCK2 | |
135 else { | |
136 unsigned long addr = inet_addr(host); | |
137 memcpy( our_s_addr, (void*)&addr, sizeof(addr) ); | |
138 } | |
139 #endif | |
140 | |
141 switch (af) { | |
142 case AF_INET: | |
143 server_address.four.sin_family=af; | |
144 server_address.four.sin_port=htons(port); | |
145 server_address_size = sizeof(server_address.four); | |
146 break; | |
147 #ifdef HAVE_AF_INET6 | |
148 case AF_INET6: | |
149 server_address.six.sin6_family=af; | |
150 server_address.six.sin6_port=htons(port); | |
151 server_address_size = sizeof(server_address.six); | |
152 break; | |
153 #endif | |
154 default: | |
155 mp_msg(MSGT_NETWORK,MSGL_ERR, MSGTR_MPDEMUX_NW_UnknownAF, af); | |
19543
e053647fbeec
Cosmetics: recommit patch changing return values to defines
reimar
parents:
19542
diff
changeset
|
156 return TCP_ERROR_FATAL; |
19542 | 157 } |
158 | |
159 #if defined(USE_ATON) || defined(HAVE_WINSOCK2) | |
160 strncpy( buf, inet_ntoa( *((struct in_addr*)our_s_addr) ), 255); | |
161 #else | |
162 inet_ntop(af, our_s_addr, buf, 255); | |
163 #endif | |
164 if(verb) mp_msg(MSGT_NETWORK,MSGL_STATUS,MSGTR_MPDEMUX_NW_ConnectingToServer, host, buf , port ); | |
165 | |
166 // Turn the socket as non blocking so we can timeout on the connection | |
167 #ifndef HAVE_WINSOCK2 | |
168 fcntl( socket_server_fd, F_SETFL, fcntl(socket_server_fd, F_GETFL) | O_NONBLOCK ); | |
169 #else | |
170 val = 1; | |
171 ioctlsocket( socket_server_fd, FIONBIO, &val ); | |
172 #endif | |
173 if( connect( socket_server_fd, (struct sockaddr*)&server_address, server_address_size )==-1 ) { | |
174 #ifndef HAVE_WINSOCK2 | |
175 if( errno!=EINPROGRESS ) { | |
176 #else | |
177 if( (WSAGetLastError() != WSAEINPROGRESS) && (WSAGetLastError() != WSAEWOULDBLOCK) ) { | |
178 #endif | |
179 if(verb) mp_msg(MSGT_NETWORK,MSGL_ERR,MSGTR_MPDEMUX_NW_CantConnect2Server, af2String(af)); | |
180 closesocket(socket_server_fd); | |
19543
e053647fbeec
Cosmetics: recommit patch changing return values to defines
reimar
parents:
19542
diff
changeset
|
181 return TCP_ERROR_PORT; |
19542 | 182 } |
183 } | |
184 tv.tv_sec = 0; | |
185 tv.tv_usec = 500000; | |
186 FD_ZERO( &set ); | |
187 FD_SET( socket_server_fd, &set ); | |
188 // When the connection will be made, we will have a writable fd | |
189 while((ret = select(socket_server_fd+1, NULL, &set, NULL, &tv)) == 0) { | |
190 if( ret<0 ) mp_msg(MSGT_NETWORK,MSGL_ERR,MSGTR_MPDEMUX_NW_SelectFailed); | |
191 else if(ret > 0) break; | |
192 else if(count > 30 || mp_input_check_interrupt(500)) { | |
193 if(count > 30) | |
194 mp_msg(MSGT_NETWORK,MSGL_ERR,MSGTR_MPDEMUX_NW_ConnTimeout); | |
195 else | |
196 mp_msg(MSGT_NETWORK,MSGL_V,"Connection interuppted by user\n"); | |
19543
e053647fbeec
Cosmetics: recommit patch changing return values to defines
reimar
parents:
19542
diff
changeset
|
197 return TCP_ERROR_TIMEOUT; |
19542 | 198 } |
199 count++; | |
200 FD_ZERO( &set ); | |
201 FD_SET( socket_server_fd, &set ); | |
202 tv.tv_sec = 0; | |
203 tv.tv_usec = 500000; | |
204 } | |
205 | |
206 // Turn back the socket as blocking | |
207 #ifndef HAVE_WINSOCK2 | |
208 fcntl( socket_server_fd, F_SETFL, fcntl(socket_server_fd, F_GETFL) & ~O_NONBLOCK ); | |
209 #else | |
210 val = 0; | |
211 ioctlsocket( socket_server_fd, FIONBIO, &val ); | |
212 #endif | |
213 // Check if there were any error | |
214 err_len = sizeof(int); | |
215 ret = getsockopt(socket_server_fd,SOL_SOCKET,SO_ERROR,&err,&err_len); | |
216 if(ret < 0) { | |
217 mp_msg(MSGT_NETWORK,MSGL_ERR,MSGTR_MPDEMUX_NW_GetSockOptFailed,strerror(errno)); | |
19543
e053647fbeec
Cosmetics: recommit patch changing return values to defines
reimar
parents:
19542
diff
changeset
|
218 return TCP_ERROR_FATAL; |
19542 | 219 } |
220 if(err > 0) { | |
221 mp_msg(MSGT_NETWORK,MSGL_ERR,MSGTR_MPDEMUX_NW_ConnectError,strerror(err)); | |
19543
e053647fbeec
Cosmetics: recommit patch changing return values to defines
reimar
parents:
19542
diff
changeset
|
222 return TCP_ERROR_PORT; |
19542 | 223 } |
224 | |
225 return socket_server_fd; | |
226 } | |
227 | |
228 // Connect to a server using a TCP connection | |
229 // return -2 for fatal error, like unable to resolve name, connection timeout... | |
230 // return -1 is unable to connect to a particular port | |
231 | |
232 | |
233 int | |
234 connect2Server(char *host, int port, int verb) { | |
235 #ifdef HAVE_AF_INET6 | |
236 int r; | |
19543
e053647fbeec
Cosmetics: recommit patch changing return values to defines
reimar
parents:
19542
diff
changeset
|
237 int s = TCP_ERROR_FATAL; |
19542 | 238 |
239 r = connect2Server_with_af(host, port, network_prefer_ipv4 ? AF_INET:AF_INET6,verb); | |
19543
e053647fbeec
Cosmetics: recommit patch changing return values to defines
reimar
parents:
19542
diff
changeset
|
240 if (r >= 0) return r; |
19542 | 241 |
242 s = connect2Server_with_af(host, port, network_prefer_ipv4 ? AF_INET6:AF_INET,verb); | |
19543
e053647fbeec
Cosmetics: recommit patch changing return values to defines
reimar
parents:
19542
diff
changeset
|
243 if (s == TCP_ERROR_FATAL) return r; |
19542 | 244 return s; |
245 #else | |
246 return connect2Server_with_af(host, port, AF_INET,verb); | |
247 #endif | |
248 | |
249 | |
250 } |