~ubuntu-branches/ubuntu/maverick/vlc/maverick

« back to all changes in this revision

Viewing changes to src/network/tcp.c

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler
  • Date: 2008-09-17 21:56:14 UTC
  • mfrom: (1.1.17 upstream)
  • Revision ID: james.westby@ubuntu.com-20080917215614-tj0vx8xzd57e52t8
Tags: 0.9.2-1ubuntu1
* New Upstream Release, exception granted by
    - dktrkranz, norsetto, Hobbsee (via irc). LP: #270404

Changes done in ubuntu:

* add libxul-dev to build-depends
* make sure that vlc is build against libxul in configure. This doesn't
  change anything in the package, but makes it more robust if building
  in an 'unclean' chroot or when modifying the package.
* debian/control: make Vcs-* fields point to the motumedia branch
* add libx264-dev and libass-dev to build-depends
  LP: #210354, #199870
* actually enable libass support by passing --enable-libass to configure
* enable libdca: add libdca-dev to build depends and --enable-libdca
* install the x264 plugin.

Changes already in the pkg-multimedia branch in debian:

* don't install usr/share/vlc/mozilla in debian/mozilla-plugin-vlc.install  
* new upstream .desktop file now registers flash video mimetype LP: #261567
* add Xb-Npp-Applications to mozilla-plugin-vlc
* remove duplicate entries in debian/vlc-nox.install

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
 *****************************************************************************
4
4
 * Copyright (C) 2004-2005 the VideoLAN team
5
5
 * Copyright (C) 2005-2006 Rémi Denis-Courmont
6
 
 * $Id: 67fc08aa8bacabcf1ba172cab1fbce65d7dd535a $
 
6
 * $Id$
7
7
 *
8
8
 * Authors: Laurent Aimar <fenrir@videolan.org>
9
9
 *          Rémi Denis-Courmont <rem # videolan.org>
26
26
/*****************************************************************************
27
27
 * Preamble
28
28
 *****************************************************************************/
29
 
#include <stdlib.h>
30
 
#include <vlc/vlc.h>
 
29
#ifdef HAVE_CONFIG_H
 
30
# include "config.h"
 
31
#endif
 
32
 
 
33
#include <vlc_common.h>
31
34
 
32
35
#include <errno.h>
 
36
#include <assert.h>
33
37
 
34
38
#ifdef HAVE_FCNTL_H
35
39
#   include <fcntl.h>
40
44
#ifdef HAVE_UNISTD_H
41
45
#   include <unistd.h>
42
46
#endif
 
47
#ifdef HAVE_POLL
 
48
# include <poll.h>
 
49
#endif
43
50
 
44
 
#include "network.h"
 
51
#include <vlc_network.h>
45
52
#if defined (WIN32) || defined (UNDER_CE)
46
53
#   undef EINPROGRESS
47
54
#   define EINPROGRESS WSAEWOULDBLOCK
51
58
#   define ETIMEDOUT WSAETIMEDOUT
52
59
#endif
53
60
 
54
 
static int SocksNegociate( vlc_object_t *, int fd, int i_socks_version,
55
 
                           char *psz_socks_user, char *psz_socks_passwd );
 
61
static int SocksNegotiate( vlc_object_t *, int fd, int i_socks_version,
 
62
                           const char *psz_user, const char *psz_passwd );
56
63
static int SocksHandshakeTCP( vlc_object_t *,
57
64
                              int fd, int i_socks_version,
58
 
                              char *psz_socks_user, char *psz_socks_passwd,
 
65
                              const char *psz_user, const char *psz_passwd,
59
66
                              const char *psz_host, int i_port );
60
67
extern int net_Socket( vlc_object_t *p_this, int i_family, int i_socktype,
61
68
                       int i_protocol );
62
 
extern int rootwrap_bind (int family, int socktype, int protocol,
63
 
                          const struct sockaddr *addr, size_t alen);
64
69
 
65
70
/*****************************************************************************
66
 
 * __net_ConnectTCP:
 
71
 * __net_Connect:
67
72
 *****************************************************************************
68
 
 * Open a TCP connection and return a handle
 
73
 * Open a network connection.
 
74
 * @return socket handler or -1 on error.
69
75
 *****************************************************************************/
70
 
int __net_ConnectTCP( vlc_object_t *p_this, const char *psz_host, int i_port )
 
76
int __net_Connect( vlc_object_t *p_this, const char *psz_host, int i_port,
 
77
                   int type, int proto )
71
78
{
72
79
    struct addrinfo hints, *res, *ptr;
73
80
    const char      *psz_realhost;
74
81
    char            *psz_socks;
75
 
    int             i_realport, i_val, i_handle = -1, i_saved_errno = 0;
76
 
    unsigned        u_errstep = 0;
 
82
    int             i_realport, i_val, i_handle = -1;
77
83
 
78
 
    if( i_port == 0 )
79
 
        i_port = 80; /* historical VLC thing */
 
84
    int evfd = vlc_object_waitpipe (p_this);
 
85
    if (evfd == -1)
 
86
        return -1;
80
87
 
81
88
    memset( &hints, 0, sizeof( hints ) );
82
89
    hints.ai_socktype = SOCK_STREAM;
83
90
 
84
 
    psz_socks = var_CreateGetString( p_this, "socks" );
85
 
    if( *psz_socks && *psz_socks != ':' )
 
91
    psz_socks = var_CreateGetNonEmptyString( p_this, "socks" );
 
92
    if( psz_socks != NULL )
86
93
    {
87
94
        char *psz = strchr( psz_socks, ':' );
88
95
 
91
98
 
92
99
        psz_realhost = psz_socks;
93
100
        i_realport = ( psz != NULL ) ? atoi( psz ) : 1080;
94
 
 
95
 
        msg_Dbg( p_this, "net: connecting to %s port %d for %s port %d",
96
 
                 psz_realhost, i_realport, psz_host, i_port );
 
101
        hints.ai_flags &= ~AI_NUMERICHOST;
 
102
 
 
103
        msg_Dbg( p_this, "net: connecting to %s port %d (SOCKS) "
 
104
                 "for %s port %d", psz_realhost, i_realport,
 
105
                 psz_host, i_port );
 
106
 
 
107
        /* We only implement TCP with SOCKS */
 
108
        switch( type )
 
109
        {
 
110
            case 0:
 
111
                type = SOCK_STREAM;
 
112
            case SOCK_STREAM:
 
113
                break;
 
114
            default:
 
115
                msg_Err( p_this, "Socket type not supported through SOCKS" );
 
116
                free( psz_socks );
 
117
                return -1;
 
118
        }
 
119
        switch( proto )
 
120
        {
 
121
            case 0:
 
122
                proto = IPPROTO_TCP;
 
123
            case IPPROTO_TCP:
 
124
                break;
 
125
            default:
 
126
                msg_Err( p_this, "Transport not supported through SOCKS" );
 
127
                free( psz_socks );
 
128
                return -1;
 
129
        }
97
130
    }
98
131
    else
99
132
    {
105
138
    }
106
139
 
107
140
    i_val = vlc_getaddrinfo( p_this, psz_realhost, i_realport, &hints, &res );
 
141
    free( psz_socks );
 
142
 
108
143
    if( i_val )
109
144
    {
110
145
        msg_Err( p_this, "cannot resolve %s port %d : %s", psz_realhost,
111
146
                 i_realport, vlc_gai_strerror( i_val ) );
112
 
        free( psz_socks );
113
147
        return -1;
114
148
    }
115
149
 
116
150
    for( ptr = res; ptr != NULL; ptr = ptr->ai_next )
117
151
    {
118
 
        int fd = net_Socket( p_this, ptr->ai_family, ptr->ai_socktype,
119
 
                             ptr->ai_protocol );
 
152
        int fd = net_Socket( p_this, ptr->ai_family, type ?: ptr->ai_socktype,
 
153
                             proto ?: ptr->ai_protocol );
120
154
        if( fd == -1 )
121
155
        {
122
 
            if( u_errstep <= 0 )
123
 
            {
124
 
                u_errstep = 1;
125
 
                i_saved_errno = net_errno;
126
 
            }
127
 
            msg_Dbg( p_this, "socket error: %s", strerror( net_errno ) );
 
156
            msg_Dbg( p_this, "socket error: %m" );
128
157
            continue;
129
158
        }
130
159
 
131
160
        if( connect( fd, ptr->ai_addr, ptr->ai_addrlen ) )
132
161
        {
133
 
            socklen_t i_val_size = sizeof( i_val );
134
 
            div_t d;
135
 
            struct timeval tv;
136
 
            vlc_value_t timeout;
 
162
            int timeout, val;
137
163
 
138
 
            if( net_errno != EINPROGRESS )
 
164
            if( net_errno != EINPROGRESS && net_errno != EINTR )
139
165
            {
140
 
                if( u_errstep <= 1 )
141
 
                {
142
 
                    u_errstep = 2;
143
 
                    i_saved_errno = net_errno;
144
 
                }
145
 
                msg_Dbg( p_this, "connect error: %s", strerror( net_errno ) );
 
166
                msg_Err( p_this, "connection failed: %m" );
146
167
                goto next_ai;
147
168
            }
 
169
            msg_Dbg( p_this, "connection: %m" );
148
170
 
149
 
            var_Create( p_this, "ipv4-timeout",
150
 
                        VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
151
 
            var_Get( p_this, "ipv4-timeout", &timeout );
152
 
            if( timeout.i_int < 0 )
 
171
            timeout = var_CreateGetInteger (p_this, "ipv4-timeout");
 
172
            if (timeout < 0)
153
173
            {
154
174
                msg_Err( p_this, "invalid negative value for ipv4-timeout" );
155
 
                timeout.i_int = 0;
156
 
            }
157
 
            d = div( timeout.i_int, 100 );
158
 
 
159
 
            msg_Dbg( p_this, "connection in progress" );
160
 
            for (;;)
161
 
            {
162
 
                fd_set fds;
163
 
                int i_ret;
164
 
 
165
 
                if( p_this->b_die )
166
 
                {
167
 
                    msg_Dbg( p_this, "connection aborted" );
168
 
                    net_Close( fd );
169
 
                    vlc_freeaddrinfo( res );
170
 
                    free( psz_socks );
171
 
                    return -1;
172
 
                }
173
 
 
174
 
                /* Initialize file descriptor set */
175
 
                FD_ZERO( &fds );
176
 
                FD_SET( fd, &fds );
177
 
 
178
 
                /*
179
 
                 * We'll wait 0.1 second if nothing happens
180
 
                 * NOTE:
181
 
                 * time out will be shortened if we catch a signal (EINTR)
182
 
                 */
183
 
                tv.tv_sec = 0;
184
 
                tv.tv_usec = (d.quot > 0) ? 100000 : (1000 * d.rem);
185
 
 
186
 
                i_ret = select( fd + 1, NULL, &fds, NULL, &tv );
187
 
                if( i_ret == 1 )
188
 
                    break;
189
 
 
190
 
                if( ( i_ret == -1 ) && ( net_errno != EINTR ) )
191
 
                {
192
 
                    msg_Warn( p_this, "select error: %s",
193
 
                              strerror( net_errno ) );
194
 
                    goto next_ai;
195
 
                }
196
 
 
197
 
                if( d.quot <= 0 )
198
 
                {
199
 
                    msg_Dbg( p_this, "select timed out" );
200
 
                    if( u_errstep <= 2 )
201
 
                    {
202
 
                        u_errstep = 3;
203
 
                        i_saved_errno = ETIMEDOUT;
204
 
                    }
205
 
                    goto next_ai;
206
 
                }
207
 
 
208
 
                d.quot--;
209
 
            }
210
 
 
211
 
#if !defined( SYS_BEOS ) && !defined( UNDER_CE )
212
 
            if( getsockopt( fd, SOL_SOCKET, SO_ERROR, (void*)&i_val,
213
 
                            &i_val_size ) == -1 || i_val != 0 )
214
 
            {
215
 
                u_errstep = 4;
216
 
                i_saved_errno = i_val;
217
 
                msg_Dbg( p_this, "connect error (via getsockopt): %s",
218
 
                         net_strerror( i_val ) );
 
175
                timeout = 0;
 
176
            }
 
177
 
 
178
            struct pollfd ufd[2] = {
 
179
                { .fd = fd,   .events = POLLOUT },
 
180
                { .fd = evfd, .events = POLLIN },
 
181
            };
 
182
 
 
183
            do
 
184
                /* NOTE: timeout screwed up if we catch a signal (EINTR) */
 
185
                val = poll (ufd, sizeof (ufd) / sizeof (ufd[0]), timeout);
 
186
            while ((val == -1) && (net_errno == EINTR));
 
187
 
 
188
            switch (val)
 
189
            {
 
190
                 case -1: /* error */
 
191
                     msg_Err (p_this, "connection polling error: %m");
 
192
                     goto next_ai;
 
193
 
 
194
                 case 0: /* timeout */
 
195
                     msg_Warn (p_this, "connection timed out");
 
196
                     goto next_ai;
 
197
 
 
198
                 default: /* something happended */
 
199
                     if (ufd[1].revents)
 
200
                         goto next_ai; /* LibVLC object killed */
 
201
            }
 
202
 
 
203
            /* There is NO WAY around checking SO_ERROR.
 
204
             * Don't ifdef it out!!! */
 
205
            if (getsockopt (fd, SOL_SOCKET, SO_ERROR, &val,
 
206
                            &(socklen_t){ sizeof (val) }) || val)
 
207
            {
 
208
                errno = val;
 
209
                msg_Err (p_this, "connection failed: %m");
219
210
                goto next_ai;
220
211
            }
221
 
#endif
222
212
        }
223
213
 
 
214
        msg_Dbg( p_this, "connection succeeded (socket = %d)", fd );
224
215
        i_handle = fd; /* success! */
225
216
        break;
226
217
 
232
223
    vlc_freeaddrinfo( res );
233
224
 
234
225
    if( i_handle == -1 )
235
 
    {
236
 
        msg_Err( p_this, "Connection to %s port %d failed: %s", psz_host,
237
 
                 i_port, net_strerror( i_saved_errno ) );
238
 
        free( psz_socks );
239
226
        return -1;
240
 
    }
241
227
 
242
 
    if( *psz_socks && *psz_socks != ':' )
 
228
    if( psz_socks != NULL )
243
229
    {
244
 
        char *psz_user = var_CreateGetString( p_this, "socks-user" );
245
 
        char *psz_pwd  = var_CreateGetString( p_this, "socks-pwd" );
 
230
        /* NOTE: psz_socks already free'd! */
 
231
        char *psz_user = var_CreateGetNonEmptyString( p_this, "socks-user" );
 
232
        char *psz_pwd  = var_CreateGetNonEmptyString( p_this, "socks-pwd" );
246
233
 
247
234
        if( SocksHandshakeTCP( p_this, i_handle, 5, psz_user, psz_pwd,
248
235
                               psz_host, i_port ) )
249
236
        {
250
 
            msg_Err( p_this, "Failed to use the SOCKS server" );
 
237
            msg_Err( p_this, "SOCKS handshake failed" );
251
238
            net_Close( i_handle );
252
239
            i_handle = -1;
253
240
        }
255
242
        free( psz_user );
256
243
        free( psz_pwd );
257
244
    }
258
 
    free( psz_socks );
259
245
 
260
246
    return i_handle;
261
247
}
262
248
 
263
249
 
264
 
/*****************************************************************************
265
 
 * __net_ListenTCP:
266
 
 *****************************************************************************
267
 
 * Open TCP passive "listening" socket(s)
268
 
 * This function returns NULL in case of error.
269
 
 *****************************************************************************/
270
 
int *__net_ListenTCP( vlc_object_t *p_this, const char *psz_host, int i_port )
 
250
int net_AcceptSingle (vlc_object_t *obj, int lfd)
271
251
{
272
 
    struct addrinfo hints, *res, *ptr;
273
 
    int             i_val, *pi_handles, i_size;
274
 
 
275
 
    memset( &hints, 0, sizeof( hints ) );
276
 
    hints.ai_socktype = SOCK_STREAM;
277
 
    hints.ai_flags = AI_PASSIVE;
278
 
 
279
 
    msg_Dbg( p_this, "net: listening to %s port %d", psz_host, i_port );
280
 
 
281
 
    i_val = vlc_getaddrinfo( p_this, psz_host, i_port, &hints, &res );
282
 
    if( i_val )
283
 
    {
284
 
        msg_Err( p_this, "Cannot resolve %s port %d : %s", psz_host, i_port,
285
 
                 vlc_gai_strerror( i_val ) );
286
 
        return NULL;
287
 
    }
288
 
 
289
 
    pi_handles = NULL;
290
 
    i_size = 1;
291
 
 
292
 
    for( ptr = res; ptr != NULL; ptr = ptr->ai_next )
293
 
    {
294
 
        int fd, *newpi;
295
 
 
296
 
        fd = net_Socket( p_this, ptr->ai_family, ptr->ai_socktype,
297
 
                         ptr->ai_protocol );
298
 
        if( fd == -1 )
299
 
        {
300
 
            msg_Dbg( p_this, "socket error: %s", net_strerror( net_errno ) );
301
 
            continue;
302
 
        }
303
 
 
304
 
        /* Bind the socket */
305
 
        if( bind( fd, ptr->ai_addr, ptr->ai_addrlen ) )
306
 
        {
307
 
            int saved_errno;
308
 
 
309
 
            saved_errno = net_errno;
310
 
            net_Close( fd );
311
 
#if !defined(WIN32) && !defined(UNDER_CE)
312
 
            fd = rootwrap_bind( ptr->ai_family, ptr->ai_socktype,
313
 
                                ptr->ai_protocol, ptr->ai_addr,
314
 
                                ptr->ai_addrlen );
315
 
            if( fd != -1 )
316
 
            {
317
 
                msg_Dbg( p_this, "got socket %d from rootwrap", fd );
318
 
            }
319
 
            else
320
 
#endif
321
 
            {
322
 
                msg_Err( p_this, "cannot bind socket (%s)",
323
 
                         net_strerror( saved_errno ) );
324
 
                continue;
325
 
            }
326
 
        }
327
 
 
328
 
        /* Listen */
329
 
        if( listen( fd, 100 ) == -1 )
330
 
        {
331
 
            msg_Err( p_this, "cannot bring the socket in listening mode (%s)",
332
 
                     net_strerror( net_errno ) );
333
 
            net_Close( fd );
334
 
            continue;
335
 
        }
336
 
 
337
 
        newpi = (int *)realloc( pi_handles, (++i_size) * sizeof( int ) );
338
 
        if( newpi == NULL )
339
 
        {
340
 
            net_Close( fd );
341
 
            break;
342
 
        }
343
 
        else
344
 
        {
345
 
            newpi[i_size - 2] = fd;
346
 
            pi_handles = newpi;
347
 
        }
348
 
    }
349
 
 
350
 
    vlc_freeaddrinfo( res );
351
 
 
352
 
    if( pi_handles != NULL )
353
 
        pi_handles[i_size - 1] = -1;
354
 
    return pi_handles;
 
252
    int fd;
 
253
    do
 
254
        fd = accept (lfd, NULL, NULL);
 
255
    while (fd == -1 && errno == EINTR);
 
256
 
 
257
    if (fd == -1)
 
258
    {
 
259
        if (net_errno != EAGAIN)
 
260
            msg_Err (obj, "accept failed (from socket %d): %m", lfd);
 
261
        return -1;
 
262
    }
 
263
 
 
264
    msg_Dbg (obj, "accepted socket %d (from socket %d)", fd, lfd);
 
265
    net_SetupSocket (fd);
 
266
    return fd;
355
267
}
356
268
 
 
269
 
357
270
/*****************************************************************************
358
271
 * __net_Accept:
359
272
 *****************************************************************************
361
274
 *****************************************************************************/
362
275
int __net_Accept( vlc_object_t *p_this, int *pi_fd, mtime_t i_wait )
363
276
{
364
 
    vlc_bool_t b_die = p_this->b_die, b_block = (i_wait < 0);
365
 
 
366
 
    while( p_this->b_die == b_die )
 
277
    int timeout = (i_wait < 0) ? -1 : i_wait / 1000;
 
278
    int evfd = vlc_object_waitpipe (p_this);
 
279
 
 
280
    if (evfd == -1)
 
281
        return -1;
 
282
 
 
283
    assert( pi_fd != NULL );
 
284
 
 
285
    for (;;)
367
286
    {
368
 
        int i_val = -1, *pi, *pi_end;
369
 
        struct timeval timeout;
370
 
        fd_set fds_r, fds_e;
371
 
 
372
 
        pi = pi_fd;
 
287
        unsigned n = 0;
 
288
        while (pi_fd[n] != -1)
 
289
            n++;
 
290
        struct pollfd ufd[n + 1];
373
291
 
374
292
        /* Initialize file descriptor set */
375
 
        FD_ZERO( &fds_r );
376
 
        FD_ZERO( &fds_e );
377
 
 
378
 
        for( pi = pi_fd; *pi != -1; pi++ )
379
 
        {
380
 
            int i_fd = *pi;
381
 
 
382
 
            if( i_fd > i_val )
383
 
                i_val = i_fd;
384
 
 
385
 
            FD_SET( i_fd, &fds_r );
386
 
            FD_SET( i_fd, &fds_e );
387
 
        }
388
 
        pi_end = pi;
389
 
 
390
 
        timeout.tv_sec = 0;
391
 
        timeout.tv_usec = b_block ? 500000 : i_wait;
392
 
 
393
 
        i_val = select( i_val + 1, &fds_r, NULL, &fds_e, &timeout );
394
 
        if( ( ( i_val < 0 ) && ( net_errno == EINTR ) ) || i_val == 0 )
395
 
        {
396
 
            if( b_block )
397
 
                continue;
398
 
            else
399
 
                return -1;
400
 
        }
401
 
        else if( i_val < 0 )
402
 
        {
403
 
            msg_Err( p_this, "network select error (%s)",
404
 
                     net_strerror( net_errno ) );
405
 
            return -1;
406
 
        }
407
 
 
408
 
        for( pi = pi_fd; *pi != -1; pi++ )
409
 
        {
410
 
            int i_fd = *pi;
411
 
 
412
 
            if( !FD_ISSET( i_fd, &fds_r ) && !FD_ISSET( i_fd, &fds_e ) )
413
 
                continue;
414
 
 
415
 
            i_val = accept( i_fd, NULL, 0 );
416
 
            if( i_val < 0 )
417
 
                msg_Err( p_this, "accept failed (%s)",
418
 
                         net_strerror( net_errno ) );
419
 
#ifndef WIN32
420
 
            else if( i_val >= FD_SETSIZE )
421
 
            {
422
 
                net_Close( i_val ); /* avoid future overflows in FD_SET */
423
 
                msg_Err( p_this, "accept failed (too many sockets opened)" );
424
 
            }
425
 
#endif
426
 
            else
427
 
            {
428
 
                const int yes = 1;
429
 
                setsockopt( i_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof( yes ));
430
 
#ifdef FD_CLOEXEC
431
 
                fcntl( i_fd, F_SETFD, FD_CLOEXEC );
432
 
#endif
433
 
                /*
434
 
                 * This round-robin trick ensures that the first sockets in
435
 
                 * pi_fd won't prevent the last ones from getting accept'ed.
436
 
                 */
437
 
                --pi_end;
438
 
                memmove( pi, pi + 1, pi_end - pi );
439
 
                *pi_end = i_fd;
440
 
                return i_val;
441
 
            }
 
293
        for (unsigned i = 0; i <= n; i++)
 
294
        {
 
295
            ufd[i].fd = (i < n) ? pi_fd[i] : evfd;
 
296
            ufd[i].events = POLLIN;
 
297
            ufd[i].revents = 0;
 
298
        }
 
299
        if (evfd == -1)
 
300
            n--; /* avoid EBADF */
 
301
 
 
302
        switch (poll (ufd, n, timeout))
 
303
        {
 
304
            case -1:
 
305
                if (net_errno == EINTR)
 
306
                    continue;
 
307
                msg_Err (p_this, "poll error: %m");
 
308
                return -1;
 
309
            case 0:
 
310
                errno = ETIMEDOUT;
 
311
                return -1;
 
312
        }
 
313
 
 
314
        if (ufd[n].revents)
 
315
        {
 
316
            errno = EINTR;
 
317
            break;
 
318
        }
 
319
 
 
320
        for (unsigned i = 0; i < n; i++)
 
321
        {
 
322
            if (ufd[i].revents == 0)
 
323
                continue;
 
324
 
 
325
            int sfd = ufd[i].fd;
 
326
            int fd = net_AcceptSingle (p_this, sfd);
 
327
            if (fd == -1)
 
328
                continue;
 
329
 
 
330
            /*
 
331
             * Move listening socket to the end to let the others in the
 
332
             * set a chance next time.
 
333
             */
 
334
            memmove (pi_fd + i, pi_fd + i + 1, n - (i + 1));
 
335
            pi_fd[n - 1] = sfd;
 
336
            return fd;
442
337
        }
443
338
    }
444
 
 
445
339
    return -1;
446
340
}
447
341
 
448
342
 
449
343
/*****************************************************************************
450
 
 * SocksNegociate:
 
344
 * SocksNegotiate:
451
345
 *****************************************************************************
452
 
 * Negociate authentication with a SOCKS server.
 
346
 * Negotiate authentication with a SOCKS server.
453
347
 *****************************************************************************/
454
 
static int SocksNegociate( vlc_object_t *p_obj,
 
348
static int SocksNegotiate( vlc_object_t *p_obj,
455
349
                           int fd, int i_socks_version,
456
 
                           char *psz_socks_user,
457
 
                           char *psz_socks_passwd )
 
350
                           const char *psz_socks_user,
 
351
                           const char *psz_socks_passwd )
458
352
{
459
353
    uint8_t buffer[128+2*256];
460
354
    int i_len;
461
 
    vlc_bool_t b_auth = VLC_FALSE;
 
355
    bool b_auth = false;
462
356
 
463
357
    if( i_socks_version != 5 )
464
358
        return VLC_SUCCESS;
465
359
 
466
 
    /* We negociate authentication */
 
360
    /* We negotiate authentication */
467
361
 
468
 
    if( psz_socks_user && psz_socks_passwd &&
469
 
        *psz_socks_user && *psz_socks_passwd )
470
 
        b_auth = VLC_TRUE;
 
362
    if( ( psz_socks_user == NULL ) && ( psz_socks_passwd == NULL ) )
 
363
        b_auth = true;
471
364
 
472
365
    buffer[0] = i_socks_version;    /* SOCKS version */
473
366
    if( b_auth )
486
379
 
487
380
    if( net_Write( p_obj, fd, NULL, buffer, i_len ) != i_len )
488
381
        return VLC_EGENERIC;
489
 
    if( net_Read( p_obj, fd, NULL, buffer, 2, VLC_TRUE ) != 2 )
 
382
    if( net_Read( p_obj, fd, NULL, buffer, 2, true ) != 2 )
490
383
        return VLC_EGENERIC;
491
384
 
492
385
    msg_Dbg( p_obj, "socks: v=%d method=%x", buffer[0], buffer[1] );
513
406
        if( net_Write( p_obj, fd, NULL, buffer, i_len ) != i_len )
514
407
            return VLC_EGENERIC;
515
408
 
516
 
        if( net_Read( p_obj, fd, NULL, buffer, 2, VLC_TRUE ) != 2 )
 
409
        if( net_Read( p_obj, fd, NULL, buffer, 2, true ) != 2 )
517
410
            return VLC_EGENERIC;
518
411
 
519
412
        msg_Dbg( p_obj, "socks: v=%d status=%x", buffer[0], buffer[1] );
544
437
static int SocksHandshakeTCP( vlc_object_t *p_obj,
545
438
                              int fd,
546
439
                              int i_socks_version,
547
 
                              char *psz_socks_user, char *psz_socks_passwd,
 
440
                              const char *psz_user, const char *psz_passwd,
548
441
                              const char *psz_host, int i_port )
549
442
{
550
443
    uint8_t buffer[128+2*256];
555
448
        i_socks_version = 5;
556
449
    }
557
450
 
558
 
    if( i_socks_version == 5 && 
559
 
        SocksNegociate( p_obj, fd, i_socks_version,
560
 
                        psz_socks_user, psz_socks_passwd ) )
 
451
    if( i_socks_version == 5 &&
 
452
        SocksNegotiate( p_obj, fd, i_socks_version,
 
453
                        psz_user, psz_passwd ) )
561
454
        return VLC_EGENERIC;
562
455
 
563
456
    if( i_socks_version == 4 )
565
458
        struct addrinfo hints, *p_res;
566
459
 
567
460
        /* v4 only support ipv4 */
568
 
        memset (&hints, 0, sizeof (hints));
 
461
        memset (&hints, 0, sizeof (hints));
569
462
        hints.ai_family = AF_INET;
570
463
        if( vlc_getaddrinfo( p_obj, psz_host, 0, &hints, &p_res ) )
571
464
            return VLC_EGENERIC;
581
474
 
582
475
        if( net_Write( p_obj, fd, NULL, buffer, 9 ) != 9 )
583
476
            return VLC_EGENERIC;
584
 
        if( net_Read( p_obj, fd, NULL, buffer, 8, VLC_TRUE ) != 8 )
 
477
        if( net_Read( p_obj, fd, NULL, buffer, 8, true ) != 8 )
585
478
            return VLC_EGENERIC;
586
479
 
587
480
        msg_Dbg( p_obj, "socks: v=%d cd=%d",
611
504
            return VLC_EGENERIC;
612
505
 
613
506
        /* Read the header */
614
 
        if( net_Read( p_obj, fd, NULL, buffer, 5, VLC_TRUE ) != 5 )
 
507
        if( net_Read( p_obj, fd, NULL, buffer, 5, true ) != 5 )
615
508
            return VLC_EGENERIC;
616
509
 
617
510
        msg_Dbg( p_obj, "socks: v=%d rep=%d atyp=%d",
630
523
            i_len = buffer[4] + 2;
631
524
        else if( buffer[3] == 0x04 )
632
525
            i_len = 16-1+2;
633
 
        else 
 
526
        else
634
527
            return VLC_EGENERIC;
635
528
 
636
 
        if( net_Read( p_obj, fd, NULL, buffer, i_len, VLC_TRUE ) != i_len )
 
529
        if( net_Read( p_obj, fd, NULL, buffer, i_len, true ) != i_len )
637
530
            return VLC_EGENERIC;
638
531
    }
639
532