2 * network helpers for UDP connections (originally borrowed from rtp.c)
4 * Copyright (C) 2006 Benjamin Zores
6 * This file is part of MPlayer.
8 * MPlayer 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.
13 * MPlayer 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.
18 * You should have received a copy of the GNU General Public License along
19 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30 #include <sys/types.h>
36 #include <netinet/in.h>
37 #include <sys/socket.h>
38 #include <arpa/inet.h>
51 /* Start listening on a UDP port. If multicast, join the group. */
53 udp_open_socket (URL_t
*url
)
55 int socket_server_fd
, rxsockbufsz
;
59 struct sockaddr_in server_address
;
63 int reuse
=reuse_socket
;
65 mp_msg (MSGT_NETWORK
, MSGL_V
,
66 "Listening for traffic on %s:%d ...\n", url
->hostname
, url
->port
);
68 socket_server_fd
= socket (AF_INET
, SOCK_DGRAM
, 0);
69 if (socket_server_fd
== -1)
71 mp_msg (MSGT_NETWORK
, MSGL_ERR
, "Failed to create socket\n");
75 if (isalpha (url
->hostname
[0]))
78 hp
= (struct hostent
*) gethostbyname (url
->hostname
);
81 mp_msg (MSGT_NETWORK
, MSGL_ERR
,
82 "Counldn't resolve name: %s\n", url
->hostname
);
83 closesocket (socket_server_fd
);
86 memcpy ((void *) &server_address
.sin_addr
.s_addr
,
87 (void *) hp
->h_addr_list
[0], hp
->h_length
);
89 server_address
.sin_addr
.s_addr
= htonl (INADDR_ANY
);
90 #endif /* HAVE_WINSOCK2_H */
95 inet_pton (AF_INET
, url
->hostname
, &server_address
.sin_addr
);
97 inet_aton (url
->hostname
, &server_address
.sin_addr
);
98 #elif !HAVE_WINSOCK2_H
99 server_address
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
102 server_address
.sin_family
= AF_INET
;
103 server_address
.sin_port
= htons (url
->port
);
105 if(reuse_socket
&& setsockopt(socket_server_fd
, SOL_SOCKET
, SO_REUSEADDR
, &reuse
, sizeof(reuse
)))
106 mp_msg(MSGT_NETWORK
, MSGL_ERR
, "SO_REUSEADDR failed! ignore.\n");
108 if (bind (socket_server_fd
, (struct sockaddr
*) &server_address
,
109 sizeof (server_address
)) == -1)
112 if (errno
!= EINPROGRESS
)
114 if (WSAGetLastError () != WSAEINPROGRESS
)
115 #endif /* HAVE_WINSOCK2_H */
117 mp_msg (MSGT_NETWORK
, MSGL_ERR
, "Failed to connect to server\n");
118 closesocket (socket_server_fd
);
124 if (isalpha (url
->hostname
[0]))
126 hp
= (struct hostent
*) gethostbyname (url
->hostname
);
129 mp_msg (MSGT_NETWORK
, MSGL_ERR
,
130 "Could not resolve name: %s\n", url
->hostname
);
131 closesocket (socket_server_fd
);
134 memcpy ((void *) &server_address
.sin_addr
.s_addr
,
135 (void *) hp
->h_addr
, hp
->h_length
);
139 unsigned int addr
= inet_addr (url
->hostname
);
140 memcpy ((void *) &server_address
.sin_addr
, (void *) &addr
, sizeof (addr
));
142 #endif /* HAVE_WINSOCK2_H */
144 /* Increase the socket rx buffer size to maximum -- this is UDP */
145 rxsockbufsz
= 240 * 1024;
146 if (setsockopt (socket_server_fd
, SOL_SOCKET
, SO_RCVBUF
,
147 &rxsockbufsz
, sizeof (rxsockbufsz
)))
149 mp_msg (MSGT_NETWORK
, MSGL_ERR
,
150 "Couldn't set receive socket buffer size\n");
153 if ((ntohl (server_address
.sin_addr
.s_addr
) >> 28) == 0xe)
155 mcast
.imr_multiaddr
.s_addr
= server_address
.sin_addr
.s_addr
;
156 mcast
.imr_interface
.s_addr
= 0;
158 if (setsockopt (socket_server_fd
, IPPROTO_IP
,
159 IP_ADD_MEMBERSHIP
, &mcast
, sizeof (mcast
)))
161 mp_msg (MSGT_NETWORK
, MSGL_ERR
, "IP_ADD_MEMBERSHIP failed (do you have multicasting enabled in your kernel?)\n");
162 closesocket (socket_server_fd
);
167 tv
.tv_sec
= 1; /* 1 second timeout */
171 FD_SET (socket_server_fd
, &set
);
173 err
= select (socket_server_fd
+ 1, &set
, NULL
, NULL
, &tv
);
176 mp_msg (MSGT_NETWORK
, MSGL_FATAL
,
177 "Select failed: %s\n", strerror (errno
));
178 closesocket (socket_server_fd
);
184 mp_msg (MSGT_NETWORK
, MSGL_ERR
,
185 "Timeout! No data from host %s\n", url
->hostname
);
186 closesocket (socket_server_fd
);
190 err_len
= sizeof (err
);
191 getsockopt (socket_server_fd
, SOL_SOCKET
, SO_ERROR
, &err
, &err_len
);
194 mp_msg (MSGT_NETWORK
, MSGL_DBG2
, "Socket error: %d\n", err
);
195 closesocket (socket_server_fd
);
199 return socket_server_fd
;