vlc_network.h 9.45 KB
Newer Older
1
/*****************************************************************************
2
 * vlc_network.h: interface to communicate with network plug-ins
3
 *****************************************************************************
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
4
 * Copyright (C) 2002-2005 VLC authors and VideoLAN
5
 * Copyright © 2006-2007 Rémi Denis-Courmont
6
 * $Id$
7
 *
8
 * Authors: Christophe Massiot <massiot@via.ecp.fr>
9
 *          Laurent Aimar <fenrir@via.ecp.fr>
10
 *          Rémi Denis-Courmont <rem # videolan.org>
11
 *
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
12 13 14
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
15 16 17 18
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
19 20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
21
 *
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
22 23 24
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
25 26
 *****************************************************************************/

27 28
#ifndef VLC_NETWORK_H
# define VLC_NETWORK_H
29

30
/**
31 32
 * \ingroup os
 * \defgroup net Networking
33
 * @{
34
 * \file
35
 * Definitions for sockets and low-level networking
36 37
 * \defgroup sockets Internet sockets
 * @{
38 39
 */

40 41 42
#include <sys/types.h>
#include <unistd.h>

43
#if defined( _WIN32 )
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
44
#   define _NO_OLDNAMES 1
45
#   include <winsock2.h>
46
#   include <ws2tcpip.h>
47
#   define net_errno (WSAGetLastError())
48
#   define net_Close(fd) ((void)closesocket((SOCKET)fd))
49
#   ifndef IPV6_V6ONLY
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
50
#       define IPV6_V6ONLY 27
51
#   endif
52
#else
53
#   include <sys/socket.h>
54
#   include <netinet/in.h>
55
#   include <netdb.h>
56
#   define net_errno errno
57
#   define net_Close(fd) ((void)vlc_close(fd))
58 59
#endif

60 61 62 63
#ifndef MSG_NOSIGNAL
# define MSG_NOSIGNAL 0
#endif

64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
/**
 * Creates a socket file descriptor.
 *
 * This function creates a socket, similar to the standard socket() function.
 * However, the new file descriptor has the close-on-exec flag set atomically,
 * so as to avoid leaking the descriptor to child processes.
 *
 * The non-blocking flag can also optionally be set.
 *
 * @param pf protocol family
 * @param type socket type
 * @param proto network protocol
 * @param nonblock true to create a non-blocking socket
 * @return a new file descriptor or -1 on error
 */
VLC_API int vlc_socket(int pf, int type, int proto, bool nonblock) VLC_USED;

/**
 * Creates a pair of socket file descriptors.
 *
 * This function creates a pair of sockets that are mutually connected,
 * much like the standard socketpair() function. However, the new file
 * descriptors have the close-on-exec flag set atomically.
 * See also vlc_socket().
 *
 * @param pf protocol family
 * @param type socket type
 * @param proto network protocol
 * @param nonblock true to create non-blocking sockets
 * @retval 0 on success
 * @retval -1 on failure
 */
VLC_API int vlc_socketpair(int pf, int type, int proto, int fds[2],
                           bool nonblock);
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
98 99

struct sockaddr;
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115

/**
 * Accepts an inbound connection request on a listening socket.
 *
 * This function creates a connected socket from a listening socket, much like
 * the standard accept() function. However, the new file descriptor has the
 * close-on-exec flag set atomically. See also vlc_socket().
 *
 * @param lfd listening socket file descriptor
 * @param addr pointer to the peer address or NULL [OUT]
 * @param alen pointer to the length of the peer address or NULL [OUT]
 * @param nonblock whether to put the new socket in non-blocking mode
 * @return a new file descriptor or -1 on error
 */
VLC_API int vlc_accept(int lfd, struct sockaddr *addr, socklen_t *alen,
                       bool nonblock) VLC_USED;
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
116

117 118 119
# ifdef __cplusplus
extern "C" {
# endif
120

121
/* Portable networking layer communication */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
122 123
int net_Socket (vlc_object_t *obj, int family, int socktype, int proto);

124
VLC_API int net_Connect(vlc_object_t *p_this, const char *psz_host, int i_port, int socktype, int protocol);
125
#define net_Connect(a, b, c, d, e) net_Connect(VLC_OBJECT(a), b, c, d, e)
126

127
VLC_API int * net_Listen(vlc_object_t *p_this, const char *psz_host, int i_port, int socktype, int protocol);
128

129 130
#define net_ListenTCP(a, b, c) net_Listen(VLC_OBJECT(a), b, c, \
                                          SOCK_STREAM, IPPROTO_TCP)
131

132
static inline int net_ConnectTCP (vlc_object_t *obj, const char *host, int port)
133
{
134
    return net_Connect (obj, host, port, SOCK_STREAM, IPPROTO_TCP);
135
}
136
#define net_ConnectTCP(a, b, c) net_ConnectTCP(VLC_OBJECT(a), b, c)
137

138
VLC_API int net_AcceptSingle(vlc_object_t *obj, int lfd);
139

140
VLC_API int net_Accept( vlc_object_t *, int * );
141 142
#define net_Accept(a, b) \
        net_Accept(VLC_OBJECT(a), b)
143

144
VLC_API int net_ConnectDgram( vlc_object_t *p_this, const char *psz_host, int i_port, int hlim, int proto );
145 146
#define net_ConnectDgram(a, b, c, d, e ) \
        net_ConnectDgram(VLC_OBJECT(a), b, c, d, e)
147 148 149

static inline int net_ConnectUDP (vlc_object_t *obj, const char *host, int port, int hlim)
{
150
    return net_ConnectDgram (obj, host, port, hlim, IPPROTO_UDP);
151
}
152

153 154 155
VLC_API int net_OpenDgram( vlc_object_t *p_this, const char *psz_bind, int i_bind, const char *psz_server, int i_server, int proto );
#define net_OpenDgram( a, b, c, d, e, g ) \
        net_OpenDgram(VLC_OBJECT(a), b, c, d, e, g)
156

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
157 158
static inline int net_ListenUDP1 (vlc_object_t *obj, const char *host, int port)
{
159
    return net_OpenDgram (obj, host, port, NULL, 0, IPPROTO_UDP);
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
160
}
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
161

162
VLC_API void net_ListenClose( int *fd );
163

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
164 165
int net_Subscribe (vlc_object_t *obj, int fd, const struct sockaddr *addr,
                   socklen_t addrlen);
166

167
VLC_API int net_SetCSCov( int fd, int sendcov, int recvcov );
168

169 170
VLC_API ssize_t net_Read( vlc_object_t *p_this, int fd, void *p_data, size_t i_data );
#define net_Read(a,b,c,d) net_Read(VLC_OBJECT(a),b,c,d)
171 172
VLC_API ssize_t net_Write( vlc_object_t *p_this, int fd, const void *p_data, size_t i_data );
#define net_Write(a,b,c,d) net_Write(VLC_OBJECT(a),b,c,d)
173 174
VLC_API char * net_Gets( vlc_object_t *p_this, int fd );
#define net_Gets(a,b) net_Gets(VLC_OBJECT(a),b)
175 176


177 178
VLC_API ssize_t net_Printf( vlc_object_t *p_this, int fd, const char *psz_fmt, ... ) VLC_FORMAT( 3, 4 );
#define net_Printf(o,fd,...) net_Printf(VLC_OBJECT(o),fd, __VA_ARGS__)
179 180
VLC_API ssize_t net_vaPrintf( vlc_object_t *p_this, int fd, const char *psz_fmt, va_list args );
#define net_vaPrintf(a,b,c,d) net_vaPrintf(VLC_OBJECT(a),b,c,d)
181

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
182
VLC_API int vlc_close(int);
183

184 185
/** @} */

186 187
/* Portable network names/addresses resolution layer */

188
#define NI_MAXNUMERICHOST 64
189

190
#ifndef AI_NUMERICSERV
191
# define AI_NUMERICSERV 0
192
#endif
193 194 195
#ifndef AI_IDN
# define AI_IDN 0 /* GNU/libc extension */
#endif
196

197
#ifdef _WIN32
198 199 200 201
# if !defined(WINAPI_FAMILY) || WINAPI_FAMILY != WINAPI_FAMILY_APP
#  undef gai_strerror
#  define gai_strerror gai_strerrorA
# endif
202 203
#endif

204
VLC_API int vlc_getnameinfo( const struct sockaddr *, int, char *, int, int *, int );
205
VLC_API int vlc_getaddrinfo (const char *, unsigned,
206
                             const struct addrinfo *, struct addrinfo **);
207 208
VLC_API int vlc_getaddrinfo_i11e(const char *, unsigned,
                                 const struct addrinfo *, struct addrinfo **);
209

210
static inline bool
211 212 213 214 215 216 217
net_SockAddrIsMulticast (const struct sockaddr *addr, socklen_t len)
{
    switch (addr->sa_family)
    {
#ifdef IN_MULTICAST
        case AF_INET:
        {
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
218
            const struct sockaddr_in *v4 = (const struct sockaddr_in *)addr;
219
            if ((size_t)len < sizeof (*v4))
220
                return false;
221
            return IN_MULTICAST (ntohl (v4->sin_addr.s_addr)) != 0;
222 223 224 225 226 227
        }
#endif

#ifdef IN6_IS_ADDR_MULTICAST
        case AF_INET6:
        {
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
228
            const struct sockaddr_in6 *v6 = (const struct sockaddr_in6 *)addr;
229
            if ((size_t)len < sizeof (*v6))
230
                return false;
231 232 233 234 235
            return IN6_IS_ADDR_MULTICAST (&v6->sin6_addr) != 0;
        }
#endif
    }

236
    return false;
237 238 239
}


240
static inline int net_GetSockAddress( int fd, char *address, int *port )
241 242 243 244
{
    struct sockaddr_storage addr;
    socklen_t addrlen = sizeof( addr );

245
    return getsockname( fd, (struct sockaddr *)&addr, &addrlen )
246 247 248 249
        || vlc_getnameinfo( (struct sockaddr *)&addr, addrlen, address,
                            NI_MAXNUMERICHOST, port, NI_NUMERICHOST )
        ? VLC_EGENERIC : 0;
}
250

251 252 253 254
static inline int net_GetPeerAddress( int fd, char *address, int *port )
{
    struct sockaddr_storage addr;
    socklen_t addrlen = sizeof( addr );
255

256 257 258 259
    return getpeername( fd, (struct sockaddr *)&addr, &addrlen )
        || vlc_getnameinfo( (struct sockaddr *)&addr, addrlen, address,
                            NI_MAXNUMERICHOST, port, NI_NUMERICHOST )
        ? VLC_EGENERIC : 0;
260 261
}

262 263 264 265 266 267 268 269 270 271 272 273 274 275
static inline uint16_t net_GetPort (const struct sockaddr *addr)
{
    switch (addr->sa_family)
    {
#ifdef AF_INET6
        case AF_INET6:
            return ((const struct sockaddr_in6 *)addr)->sin6_port;
#endif
        case AF_INET:
            return ((const struct sockaddr_in *)addr)->sin_port;
    }
    return 0;
}

276 277 278 279 280 281 282
static inline void net_SetPort (struct sockaddr *addr, uint16_t port)
{
    switch (addr->sa_family)
    {
#ifdef AF_INET6
        case AF_INET6:
            ((struct sockaddr_in6 *)addr)->sin6_port = port;
283
        break;
284 285 286
#endif
        case AF_INET:
            ((struct sockaddr_in *)addr)->sin_port = port;
287
        break;
288 289
    }
}
290 291 292

VLC_API char *vlc_getProxyUrl(const char *);

293 294 295 296
# ifdef __cplusplus
}
# endif

297 298
/** @} */

299
#endif