/*!
    Fetches information about both ends of the connection: whatever is
    available.
*/
void MSocketDevice::fetchConnectionParameters()
{
    if (!isValid())
    {
        p = 0;
        a = QHostAddress();
        pp = 0;
        pa = QHostAddress();
        return;
    }

#if !defined(QT_NO_IPV6)

    struct sockaddr_storage sa;

#else

    struct sockaddr_in sa;

#endif
    memset(&sa, 0, sizeof(sa));

    QT_SOCKLEN_T sz;

    sz = sizeof(sa);

    if (!::getsockname(fd, (struct sockaddr *)(&sa), &sz))
        qt_socket_getportaddr((struct sockaddr *)&sa, &p, &a);

    sz = sizeof(sa);

    if (!::getpeername(fd, (struct sockaddr *)(&sa), &sz))
        qt_socket_getportaddr((struct sockaddr *)&sa, &pp, &pa);
}
Exemple #2
0
void Q3SocketDevice::fetchPeerConnectionParameters()
{
    // do the getpeername() lazy on Windows (sales/arc-18/37759 claims that
    // there will be problems otherwise if you use MS Proxy server)
#if !defined (QT_NO_IPV6)
    struct qt_sockaddr_storage sa;
#else
    struct sockaddr_in sa;
#endif
    memset( &sa, 0, sizeof(sa) );
    SOCKLEN_T sz;
    sz = sizeof( sa );
    if ( !::getpeername( fd, (struct sockaddr *)(&sa), &sz ) )
	qt_socket_getportaddr( (struct sockaddr *)(&sa), &pp, &pa );
}
Exemple #3
0
/*!
    Reads \a maxlen bytes from the socket into \a data and returns the
    number of bytes read. Returns -1 if an error occurred.
*/
qint64 MSocketDevice::readData( char *data, qint64 maxlen )
{
    if ( maxlen == 0 )
        return 0;

    if ( data == 0 ) {
        VERBOSE(VB_SOCKET|VB_EXTRA,
                "MSocketDevice::readBlock: Null pointer error");
        return -1;
    }
    if ( !isValid() ) {
        VERBOSE(VB_SOCKET|VB_EXTRA,
                "MSocketDevice::readBlock: Invalid socket");
        return -1;
    }
    if ( !isOpen() ) {
        VERBOSE(VB_SOCKET|VB_EXTRA,
                "MSocketDevice::readBlock: Device is not open");
        return -1;
    }
    if ( !isReadable() ) {
        VERBOSE(VB_SOCKET|VB_EXTRA,
                "MSocketDevice::readBlock: Read operation not permitted");
        return -1;
    }

    bool done = false;
    int r = 0;
    while ( done == false ) {
	if ( t == Datagram ) {
#if !defined(QT_NO_IPV6)
            struct sockaddr_storage aa;
#else
            struct sockaddr_in aa;
#endif
	    memset( &aa, 0, sizeof(aa) );
	    QT_SOCKLEN_T sz;
	    sz = sizeof( aa );
	    r = ::recvfrom( fd, data, maxlen, 0,
			    (struct sockaddr *)&aa, &sz );

	    qt_socket_getportaddr( (struct sockaddr *)&aa, &pp, &pa);

	} else {
	    r = ::read( fd, data, maxlen );
	}
	done = true;
        if ( r == 0 && t == Stream && maxlen > 0 ) {
            // connection closed
            close();
        } else if ( r >= 0 || errno == EAGAIN || errno == EWOULDBLOCK ) {
	    // nothing
	} else if ( errno == EINTR ) {
	    done = false;
	} else if ( e == NoError ) {
	    switch( errno ) {
	    case EIO:
	    case EISDIR:
	    case EBADF:
	    case EINVAL:
	    case EFAULT:
	    case ENOTCONN:
	    case ENOTSOCK:
		e = Impossible;
		break;
#if defined(ENONET)
	    case ENONET:
#endif
	    case EHOSTUNREACH:
	    case ENETDOWN:
	    case ENETUNREACH:
	    case ETIMEDOUT:
		e = NetworkFailure;
		break;
	    case EPIPE:
	    case ECONNRESET:
		// connection closed
		close();
		r = 0;
		break;
	    default:
		e = UnknownError;
		break;
	    }
	}
    }
    return r;
}
Exemple #4
0
qint64 Q3SocketDevice::readData( char *data, qint64 maxlen )
{
#if defined(QT_CHECK_NULL)
    if ( data == 0 && maxlen != 0 ) {
	qWarning( "Q3SocketDevice::readBlock: Null pointer error" );
    }
#endif
#if defined(QT_CHECK_STATE)
    if ( !isValid() ) {
	qWarning( "Q3SocketDevice::readBlock: Invalid socket" );
	return -1;
    }
    if ( !isOpen() ) {
	qWarning( "Q3SocketDevice::readBlock: Device is not open" );
	return -1;
    }
    if ( !isReadable() ) {
	qWarning( "Q3SocketDevice::readBlock: Read operation not permitted" );
	return -1;
    }
#endif
    qint64 r = 0;
    if ( t == Datagram ) {
#if !defined(QT_NO_IPV6)
	// With IPv6 support, we must be prepared to receive both IPv4
	// and IPv6 packets. The generic SOCKADDR_STORAGE (struct
	// sockaddr_storage on unix) replaces struct sockaddr.
	struct qt_sockaddr_storage a;
#else
	struct sockaddr_in a;
#endif
	memset( &a, 0, sizeof(a) );
	SOCKLEN_T sz;
	sz = sizeof( a );
	r = ::recvfrom( fd, data, maxlen, 0, (struct sockaddr *)&a, &sz );
	qt_socket_getportaddr( (struct sockaddr *)(&a), &pp, &pa );
    } else {
	r = ::recv( fd, data, maxlen, 0 );
    }
    if ( r == 0 && t == Stream && maxlen > 0 ) {
        if ( WSAGetLastError() != WSAEWOULDBLOCK ) {
            // connection closed
            close();
        }
    } else if ( r == SOCKET_ERROR && e == NoError ) {
	switch( WSAGetLastError() ) {
	    case WSANOTINITIALISED:
		e = Impossible;
		break;
	    case WSAECONNABORTED:
	    	close();
		r = 0;
		break;
	    case WSAETIMEDOUT:
	    case WSAECONNRESET:
		/*
		From msdn doc:
		On a UDP datagram socket this error would indicate that a previous
		send operation resulted in an ICMP "Port Unreachable" message.

		So we should not close this socket just because one sendto failed.
		*/
		if ( t != Datagram )
		    close(); // connection closed
		r = 0;
		break;
	    case WSAENETDOWN:
	    case WSAENETRESET:
		e = NetworkFailure;
		break;
	    case WSAEFAULT:
	    case WSAENOTCONN:
	    case WSAESHUTDOWN:
	    case WSAEINVAL:
		e = Impossible;
		break;
	    case WSAEINTR:
		// ### ?
		r = 0;
		break;
	    case WSAEINPROGRESS:
		e = NoResources;
		break;
	    case WSAENOTSOCK:
		e = Impossible;
		break;
	    case WSAEOPNOTSUPP:
		e = InternalError; // ### ?
		break;
	    case WSAEWOULDBLOCK:
		break;
	    case WSAEMSGSIZE:
		e = NoResources; // ### ?
		break;
	    case WSAEISCONN:
		// ### ?
		r = 0;
		break;
	    default:
		e = UnknownError;
		break;
	}
    }
    return r;
}