Esempio n. 1
0
/*!
    Connects to the IP address and port specified by \a addr and \a
    port. Returns true if it establishes a connection; otherwise returns false.
    If it returns false, error() explains why.

    Note that error() commonly returns NoError for non-blocking
    sockets; this just means that you can call connect() again in a
    little while and it'll probably succeed.
*/
bool MSocketDevice::connect(const QHostAddress &addr, quint16 port)
{
    if (isValid() && addr.protocol() != pa.protocol())
    {
        close();
        fd = -1;
    }

    if (!isValid())
    {
#if !defined(QT_NO_IPV6)

        if (addr.protocol() == QAbstractSocket::IPv6Protocol)
        {
            setProtocol(IPv6);
            LOG(VB_SOCKET, LOG_INFO,
                "MSocketDevice::connect: setting Protocol to IPv6");
        }
        else
#endif
            if (addr.protocol() == QAbstractSocket::IPv4Protocol)
            {
                setProtocol(IPv4);
                LOG(VB_SOCKET, LOG_INFO,
                    "MSocketDevice::connect: setting Protocol to IPv4");
            }

        LOG(VB_SOCKET, LOG_INFO,

            "MSocketDevice::connect: attempting to create new socket");
        MSocketDevice::setSocket(createNewSocket(), t);

        // If still not valid, give up.

        if (!isValid())
            return false;
    }

    pa = addr;

    pp = port;

    struct sockaddr_in a4;

    struct sockaddr *aa;
    QT_SOCKLEN_T aalen;

#if !defined(QT_NO_IPV6)

    struct sockaddr_in6 a6;

    if (addr.protocol() == QAbstractSocket::IPv6Protocol)
    {
        memset(&a6, 0, sizeof(a6));
        a6.sin6_family = AF_INET6;
        a6.sin6_port = htons(port);
        Q_IPV6ADDR ip6 = addr.toIPv6Address();
        memcpy(&a6.sin6_addr.s6_addr, &ip6, sizeof(ip6));

        aalen = sizeof(a6);
        aa = (struct sockaddr *) & a6;
    }
    else
#endif
        if (addr.protocol() == QAbstractSocket::IPv4Protocol)
        {
            memset(&a4, 0, sizeof(a4));
            a4.sin_family = AF_INET;
            a4.sin_port = htons(port);
            a4.sin_addr.s_addr = htonl(addr.toIPv4Address());

            aalen = sizeof(a4);
            aa = (struct sockaddr *) & a4;
        }
        else
        {
            e = Impossible;
            return false;
        }

    int r = QT_SOCKET_CONNECT(fd, aa, aalen);

    if (r == 0)
    {
        fetchConnectionParameters();
        return true;
    }

    if (errno == EISCONN || errno == EALREADY || errno == EINPROGRESS)
    {
        fetchConnectionParameters();
        return true;
    }

    if (e != NoError || errno == EAGAIN || errno == EWOULDBLOCK)
    {
        return false;
    }

    switch (errno)
    {

        case EBADF:

        case ENOTSOCK:
            e = Impossible;
            break;

        case EFAULT:

        case EAFNOSUPPORT:
            e = InternalError;
            break;

        case ECONNREFUSED:
            e = ConnectionRefused;
            break;

        case ETIMEDOUT:

        case ENETUNREACH:
            e = NetworkFailure;
            break;

        case EADDRINUSE:
            e = NoResources;
            break;

        case EACCES:

        case EPERM:
            e = Inaccessible;
            break;

        default:
            e = UnknownError;
            break;
    }

    return false;
}
Esempio n. 2
0
bool Q3SocketDevice::connect( const QHostAddress &addr, Q_UINT16 port )
{
    if ( !isValid() )
	return false;

    pa = addr;
    pp = port;

    struct sockaddr_in a4;
    struct sockaddr *aa;
    QT_SOCKLEN_T aalen;

#if !defined(QT_NO_IPV6)
    struct sockaddr_in6 a6;

    if ( addr.isIPv6Address() ) {
	memset( &a6, 0, sizeof(a6) );
	a6.sin6_family = AF_INET6;
	a6.sin6_port = htons( port );
	Q_IPV6ADDR ip6 = addr.toIPv6Address();
	memcpy( &a6.sin6_addr.s6_addr, &ip6, sizeof(ip6) );

	aalen = sizeof( a6 );
	aa = (struct sockaddr *)&a6;
    } else
#endif
    if ( addr.isIPv4Address() ) {
	memset( &a4, 0, sizeof(a4) );
	a4.sin_family = AF_INET;
	a4.sin_port = htons( port );
	a4.sin_addr.s_addr = htonl( addr.toIPv4Address() );

	aalen = sizeof(a4);
	aa = (struct sockaddr *)&a4;
    } else {
	e = Impossible;
	return false;
    }

    int r = QT_SOCKET_CONNECT( fd, aa, aalen );
    if ( r == 0 ) {
	fetchConnectionParameters();
	return true;
    }
    if ( errno == EISCONN || errno == EALREADY || errno == EINPROGRESS ) {
	fetchConnectionParameters();
	return true;
    }
    if ( e != NoError || errno == EAGAIN || errno == EWOULDBLOCK ) {
	return false;
    }
    switch( errno ) {
    case EBADF:
    case ENOTSOCK:
	e = Impossible;
	break;
    case EFAULT:
    case EAFNOSUPPORT:
	e = InternalError;
	break;
    case ECONNREFUSED:
	e = ConnectionRefused;
	break;
    case ETIMEDOUT:
    case ENETUNREACH:
	e = NetworkFailure;
	break;
    case EADDRINUSE:
	e = NoResources;
	break;
    case EACCES:
    case EPERM:
	e = Inaccessible;
	break;
    default:
	e = UnknownError;
	break;
    }
    return false;
}
bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &addr, quint16 port)
{
    struct sockaddr_in sockAddrIPv4;
    struct sockaddr *sockAddrPtr = 0;
    QT_SOCKLEN_T sockAddrSize = 0;

#if !defined(QT_NO_IPV6)
    struct sockaddr_in6 sockAddrIPv6;

    if (addr.protocol() == QAbstractSocket::IPv6Protocol) {
        memset(&sockAddrIPv6, 0, sizeof(sockAddrIPv6));
        sockAddrIPv6.sin6_family = AF_INET6;
        sockAddrIPv6.sin6_port = htons(port);
#ifndef QT_NO_IPV6IFNAME
        sockAddrIPv6.sin6_scope_id = ::if_nametoindex(addr.scopeId().toLatin1().data());
#else
        sockAddrIPv6.sin6_scope_id = addr.scopeId().toInt();
#endif
        Q_IPV6ADDR ip6 = addr.toIPv6Address();
        memcpy(&sockAddrIPv6.sin6_addr.s6_addr, &ip6, sizeof(ip6));

        sockAddrSize = sizeof(sockAddrIPv6);
        sockAddrPtr = (struct sockaddr *) &sockAddrIPv6;
    } else
#if 0
    {}
#endif
#endif
    if (addr.protocol() == QAbstractSocket::IPv4Protocol) {
        memset(&sockAddrIPv4, 0, sizeof(sockAddrIPv4));
        sockAddrIPv4.sin_family = AF_INET;
        sockAddrIPv4.sin_port = htons(port);
        sockAddrIPv4.sin_addr.s_addr = htonl(addr.toIPv4Address());

        sockAddrSize = sizeof(sockAddrIPv4);
        sockAddrPtr = (struct sockaddr *) &sockAddrIPv4;
    } else {
        // unreachable
    }

    int connectResult = QT_SOCKET_CONNECT(socketDescriptor, sockAddrPtr, sockAddrSize);
    if (connectResult == -1) {
        switch (errno) {
        case EINVAL:
            setError(QAbstractSocket::UnsupportedSocketOperationError, OperationUnsupportedErrorString);
            break;
        case EISCONN:
            socketState = QAbstractSocket::ConnectedState;
            break;
        case ECONNREFUSED:
            setError(QAbstractSocket::ConnectionRefusedError, ConnectionRefusedErrorString);
            break;
        case ETIMEDOUT:
            setError(QAbstractSocket::NetworkError, ConnectionTimeOutErrorString);
            break;
        case ENETUNREACH:
            setError(QAbstractSocket::NetworkError, UnreachableErrorString);
            break;
        case EADDRINUSE:
            setError(QAbstractSocket::NetworkError, AddressInuseErrorString);
            break;
        case EINPROGRESS:
        case EALREADY:
            socketState = QAbstractSocket::ConnectingState;
            break;
        case EAGAIN:
            setError(QAbstractSocket::SocketResourceError, ResourceErrorString);
            break;
        case EACCES:
        case EPERM:
            setError(QAbstractSocket::SocketAccessError, AccessErrorString);
            break;
        case EAFNOSUPPORT:
        case EBADF:
        case EFAULT:
        case ENOTSOCK:
        default:
            break;
        }

        if (socketState != QAbstractSocket::ConnectedState) {
#if defined (QNATIVESOCKETENGINE_DEBUG)
            qDebug("QNativeSocketEnginePrivate::nativeConnect(%s, %i) == false (%s)",
                   addr.toString().toLatin1().constData(), port,
                   socketState == QAbstractSocket::ConnectingState
                   ? "Connection in progress" : socketErrorString.toLatin1().constData());
#endif
            return false;
        }
    }

#if defined (QNATIVESOCKETENGINE_DEBUG)
    qDebug("QNativeSocketEnginePrivate::nativeConnect(%s, %i) == true",
           addr.toString().toLatin1().constData(), port);
#endif

    socketState = QAbstractSocket::ConnectedState;
    return true;
}