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 memset(&server_address
, 0, sizeof(server_address
));
76 if (isalpha (url
->hostname
[0]))
79 hp
= (struct hostent
*) gethostbyname (url
->hostname
);
82 mp_msg (MSGT_NETWORK
, MSGL_ERR
,
83 "Counldn't resolve name: %s\n", url
->hostname
);
84 closesocket (socket_server_fd
);
87 memcpy ((void *) &server_address
.sin_addr
.s_addr
,
88 (void *) hp
->h_addr_list
[0], hp
->h_length
);
90 server_address
.sin_addr
.s_addr
= htonl (INADDR_ANY
);
91 #endif /* HAVE_WINSOCK2_H */
96 inet_pton (AF_INET
, url
->hostname
, &server_address
.sin_addr
);
98 inet_aton (url
->hostname
, &server_address
.sin_addr
);
99 #elif !HAVE_WINSOCK2_H
100 server_address
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
103 server_address
.sin_family
= AF_INET
;
104 server_address
.sin_port
= htons (url
->port
);
106 if(reuse_socket
&& setsockopt(socket_server_fd
, SOL_SOCKET
, SO_REUSEADDR
, &reuse
, sizeof(reuse
)))
107 mp_msg(MSGT_NETWORK
, MSGL_ERR
, "SO_REUSEADDR failed! ignore.\n");
109 if (bind (socket_server_fd
, (struct sockaddr
*) &server_address
,
110 sizeof (server_address
)) == -1)
113 if (errno
!= EINPROGRESS
)
115 if (WSAGetLastError () != WSAEINPROGRESS
)
116 #endif /* HAVE_WINSOCK2_H */
118 mp_msg (MSGT_NETWORK
, MSGL_ERR
, "Failed to connect to server\n");
119 closesocket (socket_server_fd
);
125 if (isalpha (url
->hostname
[0]))
127 hp
= (struct hostent
*) gethostbyname (url
->hostname
);
130 mp_msg (MSGT_NETWORK
, MSGL_ERR
,
131 "Could not resolve name: %s\n", url
->hostname
);
132 closesocket (socket_server_fd
);
135 memcpy ((void *) &server_address
.sin_addr
.s_addr
,
136 (void *) hp
->h_addr
, hp
->h_length
);
140 unsigned int addr
= inet_addr (url
->hostname
);
141 memcpy ((void *) &server_address
.sin_addr
, (void *) &addr
, sizeof (addr
));
143 #endif /* HAVE_WINSOCK2_H */
145 /* Increase the socket rx buffer size to maximum -- this is UDP */
146 rxsockbufsz
= 240 * 1024;
147 if (setsockopt (socket_server_fd
, SOL_SOCKET
, SO_RCVBUF
,
148 &rxsockbufsz
, sizeof (rxsockbufsz
)))
150 mp_msg (MSGT_NETWORK
, MSGL_ERR
,
151 "Couldn't set receive socket buffer size\n");
154 if ((ntohl (server_address
.sin_addr
.s_addr
) >> 28) == 0xe)
156 mcast
.imr_multiaddr
.s_addr
= server_address
.sin_addr
.s_addr
;
157 mcast
.imr_interface
.s_addr
= 0;
159 if (setsockopt (socket_server_fd
, IPPROTO_IP
,
160 IP_ADD_MEMBERSHIP
, &mcast
, sizeof (mcast
)))
162 mp_msg (MSGT_NETWORK
, MSGL_ERR
, "IP_ADD_MEMBERSHIP failed (do you have multicasting enabled in your kernel?)\n");
163 closesocket (socket_server_fd
);
168 tv
.tv_sec
= 1; /* 1 second timeout */
172 FD_SET (socket_server_fd
, &set
);
174 err
= select (socket_server_fd
+ 1, &set
, NULL
, NULL
, &tv
);
177 mp_msg (MSGT_NETWORK
, MSGL_FATAL
,
178 "Select failed: %s\n", strerror (errno
));
179 closesocket (socket_server_fd
);
185 mp_msg (MSGT_NETWORK
, MSGL_ERR
,
186 "Timeout! No data from host %s\n", url
->hostname
);
187 closesocket (socket_server_fd
);
191 err_len
= sizeof (err
);
192 getsockopt (socket_server_fd
, SOL_SOCKET
, SO_ERROR
, &err
, &err_len
);
195 mp_msg (MSGT_NETWORK
, MSGL_DBG2
, "Socket error: %d\n", err
);
196 closesocket (socket_server_fd
);
200 return socket_server_fd
;