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

📄 tcp.c

📁 uclinux 下的vlc播放器源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
        /* Listen */        if( listen( fd, 100 ) == -1 )        {            msg_Err( p_this, "cannot bring the socket in listening mode (%s)",                     net_strerror( net_errno ) );            net_Close( fd );            continue;        }        newpi = (int *)realloc( pi_handles, (++i_size) * sizeof( int ) );        if( newpi == NULL )        {            net_Close( fd );            break;        }        else        {            newpi[i_size - 2] = fd;            pi_handles = newpi;        }    }    vlc_freeaddrinfo( res );    if( pi_handles != NULL )        pi_handles[i_size - 1] = -1;    return pi_handles;}/***************************************************************************** * __net_Accept: ***************************************************************************** * Accept a connection on a set of listening sockets and return it *****************************************************************************/int __net_Accept( vlc_object_t *p_this, int *pi_fd, mtime_t i_wait ){    vlc_bool_t b_die = p_this->b_die, b_block = (i_wait < 0);    while( p_this->b_die == b_die )    {        int i_val = -1, *pi, *pi_end;        struct timeval timeout;        fd_set fds_r, fds_e;        pi = pi_fd;        /* Initialize file descriptor set */        FD_ZERO( &fds_r );        FD_ZERO( &fds_e );        for( pi = pi_fd; *pi != -1; pi++ )        {            int i_fd = *pi;            if( i_fd > i_val )                i_val = i_fd;            FD_SET( i_fd, &fds_r );            FD_SET( i_fd, &fds_e );        }        pi_end = pi;        timeout.tv_sec = 0;        timeout.tv_usec = b_block ? 500000 : i_wait;        i_val = select( i_val + 1, &fds_r, NULL, &fds_e, &timeout );        if( ( ( i_val < 0 ) && ( net_errno == EINTR ) ) || i_val == 0 )        {            if( b_block )                continue;            else                return -1;        }        else if( i_val < 0 )        {            msg_Err( p_this, "network select error (%s)",                     net_strerror( net_errno ) );            return -1;        }        for( pi = pi_fd; *pi != -1; pi++ )        {            int i_fd = *pi;            if( !FD_ISSET( i_fd, &fds_r ) && !FD_ISSET( i_fd, &fds_e ) )                continue;            i_val = accept( i_fd, NULL, 0 );            if( i_val < 0 )                msg_Err( p_this, "accept failed (%s)",                         net_strerror( net_errno ) );#ifndef WIN32            else if( i_val >= FD_SETSIZE )            {                net_Close( i_val ); /* avoid future overflows in FD_SET */                msg_Err( p_this, "accept failed (too many sockets opened)" );            }#endif            else            {                const int yes = 1;                setsockopt( i_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof( yes ));#ifdef FD_CLOEXEC                fcntl( i_fd, F_SETFD, FD_CLOEXEC );#endif                /*                 * This round-robin trick ensures that the first sockets in                 * pi_fd won't prevent the last ones from getting accept'ed.                 */                --pi_end;                memmove( pi, pi + 1, pi_end - pi );                *pi_end = i_fd;                return i_val;            }        }    }    return -1;}/***************************************************************************** * SocksNegociate: ***************************************************************************** * Negociate authentication with a SOCKS server. *****************************************************************************/static int SocksNegociate( vlc_object_t *p_obj,                           int fd, int i_socks_version,                           char *psz_socks_user,                           char *psz_socks_passwd ){    uint8_t buffer[128+2*256];    int i_len;    vlc_bool_t b_auth = VLC_FALSE;    if( i_socks_version != 5 )        return VLC_SUCCESS;    /* We negociate authentication */    if( psz_socks_user && psz_socks_passwd &&        *psz_socks_user && *psz_socks_passwd )        b_auth = VLC_TRUE;    buffer[0] = i_socks_version;    /* SOCKS version */    if( b_auth )    {        buffer[1] = 2;                  /* Number of methods */        buffer[2] = 0x00;               /* - No auth required */        buffer[3] = 0x02;               /* - USer/Password */        i_len = 4;    }    else    {        buffer[1] = 1;                  /* Number of methods */        buffer[2] = 0x00;               /* - No auth required */        i_len = 3;    }    if( net_Write( p_obj, fd, NULL, buffer, i_len ) != i_len )        return VLC_EGENERIC;    if( net_Read( p_obj, fd, NULL, buffer, 2, VLC_TRUE ) != 2 )        return VLC_EGENERIC;    msg_Dbg( p_obj, "socks: v=%d method=%x", buffer[0], buffer[1] );    if( buffer[1] == 0x00 )    {        msg_Dbg( p_obj, "socks: no authentication required" );    }    else if( buffer[1] == 0x02 )    {        int i_len1 = __MIN( strlen(psz_socks_user), 255 );        int i_len2 = __MIN( strlen(psz_socks_passwd), 255 );        msg_Dbg( p_obj, "socks: username/password authentication" );        /* XXX: we don't support user/pwd > 255 (truncated)*/        buffer[0] = i_socks_version;        /* Version */        buffer[1] = i_len1;                 /* User length */        memcpy( &buffer[2], psz_socks_user, i_len1 );        buffer[2+i_len1] = i_len2;          /* Password length */        memcpy( &buffer[2+i_len1+1], psz_socks_passwd, i_len2 );        i_len = 3 + i_len1 + i_len2;        if( net_Write( p_obj, fd, NULL, buffer, i_len ) != i_len )            return VLC_EGENERIC;        if( net_Read( p_obj, fd, NULL, buffer, 2, VLC_TRUE ) != 2 )            return VLC_EGENERIC;        msg_Dbg( p_obj, "socks: v=%d status=%x", buffer[0], buffer[1] );        if( buffer[1] != 0x00 )        {            msg_Err( p_obj, "socks: authentication rejected" );            return VLC_EGENERIC;        }    }    else    {        if( b_auth )            msg_Err( p_obj, "socks: unsupported authentication method %x",                     buffer[0] );        else            msg_Err( p_obj, "socks: authentification needed" );        return VLC_EGENERIC;    }    return VLC_SUCCESS;}/***************************************************************************** * SocksHandshakeTCP: ***************************************************************************** * Open a TCP connection using a SOCKS server and return a handle (RFC 1928) *****************************************************************************/static int SocksHandshakeTCP( vlc_object_t *p_obj,                              int fd,                              int i_socks_version,                              char *psz_socks_user, char *psz_socks_passwd,                              const char *psz_host, int i_port ){    uint8_t buffer[128+2*256];    if( i_socks_version != 4 && i_socks_version != 5 )    {        msg_Warn( p_obj, "invalid socks protocol version %d", i_socks_version );        i_socks_version = 5;    }    if( i_socks_version == 5 &&         SocksNegociate( p_obj, fd, i_socks_version,                        psz_socks_user, psz_socks_passwd ) )        return VLC_EGENERIC;    if( i_socks_version == 4 )    {        struct addrinfo hints, *p_res;        /* v4 only support ipv4 */	memset (&hints, 0, sizeof (hints));        hints.ai_family = AF_INET;        if( vlc_getaddrinfo( p_obj, psz_host, 0, &hints, &p_res ) )            return VLC_EGENERIC;        buffer[0] = i_socks_version;        buffer[1] = 0x01;               /* CONNECT */        SetWBE( &buffer[2], i_port );   /* Port */        memcpy( &buffer[4],             /* Address */                &((struct sockaddr_in *)(p_res->ai_addr))->sin_addr, 4 );        vlc_freeaddrinfo( p_res );        buffer[8] = 0;                  /* Empty user id */        if( net_Write( p_obj, fd, NULL, buffer, 9 ) != 9 )            return VLC_EGENERIC;        if( net_Read( p_obj, fd, NULL, buffer, 8, VLC_TRUE ) != 8 )            return VLC_EGENERIC;        msg_Dbg( p_obj, "socks: v=%d cd=%d",                 buffer[0], buffer[1] );        if( buffer[1] != 90 )            return VLC_EGENERIC;    }    else if( i_socks_version == 5 )    {        int i_hlen = __MIN(strlen( psz_host ), 255);        int i_len;        buffer[0] = i_socks_version;    /* Version */        buffer[1] = 0x01;               /* Cmd: connect */        buffer[2] = 0x00;               /* Reserved */        buffer[3] = 3;                  /* ATYP: for now domainname */        buffer[4] = i_hlen;        memcpy( &buffer[5], psz_host, i_hlen );        SetWBE( &buffer[5+i_hlen], i_port );        i_len = 5 + i_hlen + 2;        if( net_Write( p_obj, fd, NULL, buffer, i_len ) != i_len )            return VLC_EGENERIC;        /* Read the header */        if( net_Read( p_obj, fd, NULL, buffer, 5, VLC_TRUE ) != 5 )            return VLC_EGENERIC;        msg_Dbg( p_obj, "socks: v=%d rep=%d atyp=%d",                 buffer[0], buffer[1], buffer[3] );        if( buffer[1] != 0x00 )        {            msg_Err( p_obj, "socks: CONNECT request failed\n" );            return VLC_EGENERIC;        }        /* Read the remaining bytes */        if( buffer[3] == 0x01 )            i_len = 4-1 + 2;        else if( buffer[3] == 0x03 )            i_len = buffer[4] + 2;        else if( buffer[3] == 0x04 )            i_len = 16-1+2;        else             return VLC_EGENERIC;        if( net_Read( p_obj, fd, NULL, buffer, i_len, VLC_TRUE ) != i_len )            return VLC_EGENERIC;    }    return VLC_SUCCESS;}void net_ListenClose( int *pi_fd ){    if( pi_fd != NULL )    {        int *pi;        for( pi = pi_fd; *pi != -1; pi++ )            net_Close( *pi );        free( pi_fd );    }}

⌨️ 快捷键说明

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