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

📄 tcp.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************** * tcp.c: ***************************************************************************** * Copyright (C) 2004-2005 the VideoLAN team * Copyright (C) 2005-2006 Rémi Denis-Courmont * $Id$ * * 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 *****************************************************************************/#ifdef HAVE_CONFIG_H# include "config.h"#endif#include <vlc_common.h>#include <errno.h>#include <assert.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#ifdef HAVE_POLL# include <poll.h>#endif#include <vlc_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 SocksNegotiate( vlc_object_t *, int fd, int i_socks_version,                           const char *psz_user, const char *psz_passwd );static int SocksHandshakeTCP( vlc_object_t *,                              int fd, int i_socks_version,                              const char *psz_user, const char *psz_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 );/***************************************************************************** * __net_Connect: ***************************************************************************** * Open a network connection. * @return socket handler or -1 on error. *****************************************************************************/int __net_Connect( vlc_object_t *p_this, const char *psz_host, int i_port,                   int type, int proto ){    struct addrinfo hints, *res, *ptr;    const char      *psz_realhost;    char            *psz_socks;    int             i_realport, i_val, i_handle = -1;    int evfd = vlc_object_waitpipe (p_this);    if (evfd == -1)        return -1;    memset( &hints, 0, sizeof( hints ) );    hints.ai_socktype = SOCK_STREAM;    psz_socks = var_CreateGetNonEmptyString( p_this, "socks" );    if( psz_socks != NULL )    {        char *psz = strchr( psz_socks, ':' );        if( psz )            *psz++ = '\0';        psz_realhost = psz_socks;        i_realport = ( psz != NULL ) ? atoi( psz ) : 1080;        hints.ai_flags &= ~AI_NUMERICHOST;        msg_Dbg( p_this, "net: connecting to %s port %d (SOCKS) "                 "for %s port %d", psz_realhost, i_realport,                 psz_host, i_port );        /* We only implement TCP with SOCKS */        switch( type )        {            case 0:                type = SOCK_STREAM;            case SOCK_STREAM:                break;            default:                msg_Err( p_this, "Socket type not supported through SOCKS" );                free( psz_socks );                return -1;        }        switch( proto )        {            case 0:                proto = IPPROTO_TCP;            case IPPROTO_TCP:                break;            default:                msg_Err( p_this, "Transport not supported through SOCKS" );                free( psz_socks );                return -1;        }    }    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 );    free( psz_socks );    if( i_val )    {        msg_Err( p_this, "cannot resolve %s port %d : %s", psz_realhost,                 i_realport, vlc_gai_strerror( i_val ) );        return -1;    }    for( ptr = res; ptr != NULL; ptr = ptr->ai_next )    {        int fd = net_Socket( p_this, ptr->ai_family, type ?: ptr->ai_socktype,                             proto ?: ptr->ai_protocol );        if( fd == -1 )        {            msg_Dbg( p_this, "socket error: %m" );            continue;        }        if( connect( fd, ptr->ai_addr, ptr->ai_addrlen ) )        {            int timeout, val;            if( net_errno != EINPROGRESS && net_errno != EINTR )            {                msg_Err( p_this, "connection failed: %m" );                goto next_ai;            }            msg_Dbg( p_this, "connection: %m" );            timeout = var_CreateGetInteger (p_this, "ipv4-timeout");            if (timeout < 0)            {                msg_Err( p_this, "invalid negative value for ipv4-timeout" );                timeout = 0;            }            struct pollfd ufd[2] = {                { .fd = fd,   .events = POLLOUT },                { .fd = evfd, .events = POLLIN },            };            do                /* NOTE: timeout screwed up if we catch a signal (EINTR) */                val = poll (ufd, sizeof (ufd) / sizeof (ufd[0]), timeout);            while ((val == -1) && (net_errno == EINTR));            switch (val)            {                 case -1: /* error */                     msg_Err (p_this, "connection polling error: %m");                     goto next_ai;                 case 0: /* timeout */                     msg_Warn (p_this, "connection timed out");                     goto next_ai;                 default: /* something happended */                     if (ufd[1].revents)                         goto next_ai; /* LibVLC object killed */            }            /* There is NO WAY around checking SO_ERROR.             * Don't ifdef it out!!! */            if (getsockopt (fd, SOL_SOCKET, SO_ERROR, &val,                            &(socklen_t){ sizeof (val) }) || val)            {                errno = val;                msg_Err (p_this, "connection failed: %m");                goto next_ai;            }        }        msg_Dbg( p_this, "connection succeeded (socket = %d)", fd );        i_handle = fd; /* success! */        break;next_ai: /* failure */        net_Close( fd );        continue;    }    vlc_freeaddrinfo( res );    if( i_handle == -1 )        return -1;    if( psz_socks != NULL )    {        /* NOTE: psz_socks already free'd! */        char *psz_user = var_CreateGetNonEmptyString( p_this, "socks-user" );        char *psz_pwd  = var_CreateGetNonEmptyString( p_this, "socks-pwd" );        if( SocksHandshakeTCP( p_this, i_handle, 5, psz_user, psz_pwd,                               psz_host, i_port ) )        {            msg_Err( p_this, "SOCKS handshake failed" );            net_Close( i_handle );            i_handle = -1;        }        free( psz_user );        free( psz_pwd );    }    return i_handle;}int net_AcceptSingle (vlc_object_t *obj, int lfd){    int fd;    do        fd = accept (lfd, NULL, NULL);    while (fd == -1 && errno == EINTR);    if (fd == -1)    {        if (net_errno != EAGAIN)            msg_Err (obj, "accept failed (from socket %d): %m", lfd);        return -1;    }    msg_Dbg (obj, "accepted socket %d (from socket %d)", fd, lfd);    net_SetupSocket (fd);    return fd;}/***************************************************************************** * __net_Accept: ***************************************************************************** * Accept a connection on a set of listening sockets and return it *****************************************************************************/

⌨️ 快捷键说明

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