⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcp.c

📁 uclinux 下的vlc播放器源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************** * tcp.c: ***************************************************************************** * Copyright (C) 2004-2005 the VideoLAN team * Copyright (C) 2005-2006 Rémi Denis-Courmont * $Id: tcp.c 16544 2006-09-07 23:05:11Z hartman $ * * Authors: Laurent Aimar <fenrir@videolan.org> *          Rémi Denis-Courmont <rem # videolan.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (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 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU 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. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#include <stdlib.h>#include <vlc/vlc.h>#include <errno.h>#ifdef HAVE_FCNTL_H#   include <fcntl.h>#endif#ifdef HAVE_SYS_TIME_H#    include <sys/time.h>#endif#ifdef HAVE_UNISTD_H#   include <unistd.h>#endif#include "network.h"#if defined (WIN32) || defined (UNDER_CE)#   undef EINPROGRESS#   define EINPROGRESS WSAEWOULDBLOCK#   undef EINTR#   define EINTR WSAEINTR#   undef ETIMEDOUT#   define ETIMEDOUT WSAETIMEDOUT#endifstatic int SocksNegociate( vlc_object_t *, int fd, int i_socks_version,                           char *psz_socks_user, char *psz_socks_passwd );static int SocksHandshakeTCP( vlc_object_t *,                              int fd, int i_socks_version,                              char *psz_socks_user, char *psz_socks_passwd,                              const char *psz_host, int i_port );extern int net_Socket( vlc_object_t *p_this, int i_family, int i_socktype,                       int i_protocol );extern int rootwrap_bind (int family, int socktype, int protocol,                          const struct sockaddr *addr, size_t alen);/***************************************************************************** * __net_ConnectTCP: ***************************************************************************** * Open a TCP connection and return a handle *****************************************************************************/int __net_ConnectTCP( vlc_object_t *p_this, const char *psz_host, int i_port ){    struct addrinfo hints, *res, *ptr;    const char      *psz_realhost;    char            *psz_socks;    int             i_realport, i_val, i_handle = -1, i_saved_errno = 0;    unsigned        u_errstep = 0;    if( i_port == 0 )        i_port = 80; /* historical VLC thing */    memset( &hints, 0, sizeof( hints ) );    hints.ai_socktype = SOCK_STREAM;    psz_socks = var_CreateGetString( p_this, "socks" );    if( *psz_socks && *psz_socks != ':' )    {        char *psz = strchr( psz_socks, ':' );        if( psz )            *psz++ = '\0';        psz_realhost = psz_socks;        i_realport = ( psz != NULL ) ? atoi( psz ) : 1080;        msg_Dbg( p_this, "net: connecting to %s port %d for %s port %d",                 psz_realhost, i_realport, psz_host, i_port );    }    else    {        psz_realhost = psz_host;        i_realport = i_port;        msg_Dbg( p_this, "net: connecting to %s port %d", psz_realhost,                 i_realport );    }    i_val = vlc_getaddrinfo( p_this, psz_realhost, i_realport, &hints, &res );    if( i_val )    {        msg_Err( p_this, "cannot resolve %s port %d : %s", psz_realhost,                 i_realport, vlc_gai_strerror( i_val ) );        free( psz_socks );        return -1;    }    for( ptr = res; ptr != NULL; ptr = ptr->ai_next )    {        int fd = net_Socket( p_this, ptr->ai_family, ptr->ai_socktype,                             ptr->ai_protocol );        if( fd == -1 )        {            if( u_errstep <= 0 )            {                u_errstep = 1;                i_saved_errno = net_errno;            }            msg_Dbg( p_this, "socket error: %s", strerror( net_errno ) );            continue;        }        if( connect( fd, ptr->ai_addr, ptr->ai_addrlen ) )        {            socklen_t i_val_size = sizeof( i_val );            div_t d;            struct timeval tv;            vlc_value_t timeout;            if( net_errno != EINPROGRESS )            {                if( u_errstep <= 1 )                {                    u_errstep = 2;                    i_saved_errno = net_errno;                }                msg_Dbg( p_this, "connect error: %s", strerror( net_errno ) );                goto next_ai;            }            var_Create( p_this, "ipv4-timeout",                        VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );            var_Get( p_this, "ipv4-timeout", &timeout );            if( timeout.i_int < 0 )            {                msg_Err( p_this, "invalid negative value for ipv4-timeout" );                timeout.i_int = 0;            }            d = div( timeout.i_int, 100 );            msg_Dbg( p_this, "connection in progress" );            for (;;)            {                fd_set fds;                int i_ret;                if( p_this->b_die )                {                    msg_Dbg( p_this, "connection aborted" );                    net_Close( fd );                    vlc_freeaddrinfo( res );                    free( psz_socks );                    return -1;                }                /* Initialize file descriptor set */                FD_ZERO( &fds );                FD_SET( fd, &fds );                /*                 * We'll wait 0.1 second if nothing happens                 * NOTE:                 * time out will be shortened if we catch a signal (EINTR)                 */                tv.tv_sec = 0;                tv.tv_usec = (d.quot > 0) ? 100000 : (1000 * d.rem);                i_ret = select( fd + 1, NULL, &fds, NULL, &tv );                if( i_ret == 1 )                    break;                if( ( i_ret == -1 ) && ( net_errno != EINTR ) )                {                    msg_Warn( p_this, "select error: %s",                              strerror( net_errno ) );                    goto next_ai;                }                if( d.quot <= 0 )                {                    msg_Dbg( p_this, "select timed out" );                    if( u_errstep <= 2 )                    {                        u_errstep = 3;                        i_saved_errno = ETIMEDOUT;                    }                    goto next_ai;                }                d.quot--;            }#if !defined( SYS_BEOS ) && !defined( UNDER_CE )            if( getsockopt( fd, SOL_SOCKET, SO_ERROR, (void*)&i_val,                            &i_val_size ) == -1 || i_val != 0 )            {                u_errstep = 4;                i_saved_errno = i_val;                msg_Dbg( p_this, "connect error (via getsockopt): %s",                         net_strerror( i_val ) );                goto next_ai;            }#endif        }        i_handle = fd; /* success! */        break;next_ai: /* failure */        net_Close( fd );        continue;    }    vlc_freeaddrinfo( res );    if( i_handle == -1 )    {        msg_Err( p_this, "Connection to %s port %d failed: %s", psz_host,                 i_port, net_strerror( i_saved_errno ) );        free( psz_socks );        return -1;    }    if( *psz_socks && *psz_socks != ':' )    {        char *psz_user = var_CreateGetString( p_this, "socks-user" );        char *psz_pwd  = var_CreateGetString( p_this, "socks-pwd" );        if( SocksHandshakeTCP( p_this, i_handle, 5, psz_user, psz_pwd,                               psz_host, i_port ) )        {            msg_Err( p_this, "Failed to use the SOCKS server" );            net_Close( i_handle );            i_handle = -1;        }        free( psz_user );        free( psz_pwd );    }    free( psz_socks );    return i_handle;}/***************************************************************************** * __net_ListenTCP: ***************************************************************************** * Open TCP passive "listening" socket(s) * This function returns NULL in case of error. *****************************************************************************/int *__net_ListenTCP( vlc_object_t *p_this, const char *psz_host, int i_port ){    struct addrinfo hints, *res, *ptr;    int             i_val, *pi_handles, i_size;    memset( &hints, 0, sizeof( hints ) );    hints.ai_socktype = SOCK_STREAM;    hints.ai_flags = AI_PASSIVE;    msg_Dbg( p_this, "net: listening to %s port %d", psz_host, i_port );    i_val = vlc_getaddrinfo( p_this, psz_host, i_port, &hints, &res );    if( i_val )    {        msg_Err( p_this, "Cannot resolve %s port %d : %s", psz_host, i_port,                 vlc_gai_strerror( i_val ) );        return NULL;    }    pi_handles = NULL;    i_size = 1;    for( ptr = res; ptr != NULL; ptr = ptr->ai_next )    {        int fd, *newpi;        fd = net_Socket( p_this, ptr->ai_family, ptr->ai_socktype,                         ptr->ai_protocol );        if( fd == -1 )        {            msg_Dbg( p_this, "socket error: %s", net_strerror( net_errno ) );            continue;        }        /* Bind the socket */        if( bind( fd, ptr->ai_addr, ptr->ai_addrlen ) )        {            int saved_errno;            saved_errno = net_errno;            net_Close( fd );#if !defined(WIN32) && !defined(UNDER_CE)            fd = rootwrap_bind( ptr->ai_family, ptr->ai_socktype,                                ptr->ai_protocol, ptr->ai_addr,                                ptr->ai_addrlen );            if( fd != -1 )            {                msg_Dbg( p_this, "got socket %d from rootwrap", fd );            }            else#endif            {                msg_Err( p_this, "cannot bind socket (%s)",                         net_strerror( saved_errno ) );                continue;            }        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -