Пример #1
0
boolean tcp_connect(rdpTcp* tcp, const char* hostname, uint16 port)
{
	uint32 option_value;
	socklen_t option_len;

	tcp->sockfd = freerdp_tcp_connect(hostname, port);

	if (tcp->sockfd < 0)
		return false;

	tcp_get_ip_address(tcp);
	tcp_get_mac_address(tcp);

	option_value = 1;
	option_len = sizeof(option_value);
	setsockopt(tcp->sockfd, IPPROTO_TCP, TCP_NODELAY, (void*) &option_value, option_len);

	/* receive buffer must be a least 32 K */
	if (getsockopt(tcp->sockfd, SOL_SOCKET, SO_RCVBUF, (void*) &option_value, &option_len) == 0)
	{
		if (option_value < (1024 * 32))
		{
			option_value = 1024 * 32;
			option_len = sizeof(option_value);
			setsockopt(tcp->sockfd, SOL_SOCKET, SO_RCVBUF, (void*) &option_value, option_len);
		}
	}

	tcp_set_keep_alive_mode(tcp);

	return true;
}
Пример #2
0
BOOL tcp_connect(rdpTcp* tcp, const char* hostname, UINT16 port)
{
	UINT32 option_value;
	socklen_t option_len;

	if (hostname == NULL)
		return FALSE;

	if (hostname[0] == '/')
	{
		tcp->sockfd = freerdp_uds_connect(hostname);

		if (tcp->sockfd < 0)
			return FALSE;
	}
	else
	{
		tcp->sockfd = freerdp_tcp_connect(hostname, port);

		if (tcp->sockfd < 0)
			return FALSE;

		SetEventFileDescriptor(tcp->event, tcp->sockfd);

		tcp_get_ip_address(tcp);
		tcp_get_mac_address(tcp);

		option_value = 1;
		option_len = sizeof(option_value);
		setsockopt(tcp->sockfd, IPPROTO_TCP, TCP_NODELAY, (void*) &option_value, option_len);

		/* receive buffer must be a least 32 K */
		if (getsockopt(tcp->sockfd, SOL_SOCKET, SO_RCVBUF, (void*) &option_value, &option_len) == 0)
		{
			if (option_value < (1024 * 32))
			{
				option_value = 1024 * 32;
				option_len = sizeof(option_value);
				setsockopt(tcp->sockfd, SOL_SOCKET, SO_RCVBUF, (void*) &option_value, option_len);
			}
		}

		tcp_set_keep_alive_mode(tcp);
	}

	return TRUE;
}
Пример #3
0
BOOL tcp_connect(rdpTcp* tcp, const char* hostname, int port, int timeout)
{
	int status;
	UINT32 option_value;
	socklen_t option_len;

	if (!hostname)
		return FALSE;

	if (hostname[0] == '/')
	{
		tcp->sockfd = freerdp_uds_connect(hostname);

		if (tcp->sockfd < 0)
			return FALSE;

		tcp->socketBio = BIO_new_fd(tcp->sockfd, 1);

		if (!tcp->socketBio)
			return FALSE;
	}
	else
	{
		fd_set cfds;
		struct timeval tv;

		tcp->socketBio = BIO_new(BIO_s_connect());

		if (!tcp->socketBio)
			return FALSE;

		if (BIO_set_conn_hostname(tcp->socketBio, hostname) < 0 || BIO_set_conn_int_port(tcp->socketBio, &port) < 0)
			return FALSE;

		BIO_set_nbio(tcp->socketBio, 1);

		status = BIO_do_connect(tcp->socketBio);

		if ((status <= 0) && !BIO_should_retry(tcp->socketBio))
			return FALSE;

		tcp->sockfd = BIO_get_fd(tcp->socketBio, NULL);

		if (tcp->sockfd < 0)
			return FALSE;

		if (status <= 0)
		{
			FD_ZERO(&cfds);
			FD_SET(tcp->sockfd, &cfds);

			tv.tv_sec = timeout;
			tv.tv_usec = 0;

			status = select(tcp->sockfd + 1, NULL, &cfds, NULL, &tv);

			if (status == 0)
			{
				return FALSE; /* timeout */
			}
		}

		BIO_set_close(tcp->socketBio, BIO_NOCLOSE);
		BIO_free(tcp->socketBio);

		tcp->socketBio = BIO_new(BIO_s_simple_socket());

		if (!tcp->socketBio)
			return -1;

		BIO_set_fd(tcp->socketBio, tcp->sockfd, BIO_CLOSE);
	}

	SetEventFileDescriptor(tcp->event, tcp->sockfd);

	tcp_get_ip_address(tcp);
	tcp_get_mac_address(tcp);

	option_value = 1;
	option_len = sizeof(option_value);

	if (setsockopt(tcp->sockfd, IPPROTO_TCP, TCP_NODELAY, (void*) &option_value, option_len) < 0)
		fprintf(stderr, "%s: unable to set TCP_NODELAY\n", __FUNCTION__);

	/* receive buffer must be a least 32 K */
	if (getsockopt(tcp->sockfd, SOL_SOCKET, SO_RCVBUF, (void*) &option_value, &option_len) == 0)
	{
		if (option_value < (1024 * 32))
		{
			option_value = 1024 * 32;
			option_len = sizeof(option_value);

			if (setsockopt(tcp->sockfd, SOL_SOCKET, SO_RCVBUF, (void*) &option_value, option_len) < 0)
			{
				fprintf(stderr, "%s: unable to set receive buffer len\n", __FUNCTION__);
				return FALSE;
			}
		}
	}

	if (!tcp_set_keep_alive_mode(tcp))
		return FALSE;

	tcp->bufferedBio = BIO_new(BIO_s_buffered_socket());

	if (!tcp->bufferedBio)
		return FALSE;

	tcp->bufferedBio->ptr = tcp;

	tcp->bufferedBio = BIO_push(tcp->bufferedBio, tcp->socketBio);

	return TRUE;
}
Пример #4
0
boolean tcp_connect(rdpTcp* tcp, const char* hostname, uint16 port)
{
    int status;
    char servname[10];
    uint32 option_value;
    socklen_t option_len;
    struct addrinfo hints = { 0 };
    struct addrinfo * res, * ai;

    memset(&hints, 0, sizeof(struct addrinfo));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;

    snprintf(servname, sizeof(servname), "%d", port);
    status = getaddrinfo(hostname, servname, &hints, &res);

    if (status != 0)
    {
        printf("tcp_connect: getaddrinfo (%s)\n", gai_strerror(status));
        return false;
    }

    tcp->sockfd = -1;
    for (ai = res; ai; ai = ai->ai_next)
    {
        tcp->sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);

        if (tcp->sockfd < 0)
            continue;

        if (connect(tcp->sockfd, ai->ai_addr, ai->ai_addrlen) == 0)
        {
            printf("connected to %s:%s\n", hostname, servname);
            break;
        }

        close(tcp->sockfd);
        tcp->sockfd = -1;
    }
    freeaddrinfo(res);

    if (tcp->sockfd == -1)
    {
        printf("unable to connect to %s:%s\n", hostname, servname);
        return false;
    }

    tcp_get_ip_address(tcp);
    tcp_get_mac_address(tcp);

    option_value = 1;
    option_len = sizeof(option_value);
    setsockopt(tcp->sockfd, IPPROTO_TCP, TCP_NODELAY, (void*) &option_value, option_len);

    /* receive buffer must be a least 32 K */
    if (getsockopt(tcp->sockfd, SOL_SOCKET, SO_RCVBUF, (void*) &option_value, &option_len) == 0)
    {
        if (option_value < (1024 * 32))
        {
            option_value = 1024 * 32;
            option_len = sizeof(option_value);
            setsockopt(tcp->sockfd, SOL_SOCKET, SO_RCVBUF, (void*) &option_value, option_len);
        }
    }

    tcp_set_keep_alive_mode(tcp);

    return true;
}
Пример #5
0
BOOL tcp_connect(rdpTcp* tcp, const char* hostname, int port, int timeout)
{
	int status;
	UINT32 option_value;
	socklen_t option_len;

	if (!hostname)
		return FALSE;

	if (hostname[0] == '/')
		tcp->ipcSocket = TRUE;

	if (tcp->ipcSocket)
	{
		tcp->sockfd = freerdp_uds_connect(hostname);

		if (tcp->sockfd < 0)
			return FALSE;

		tcp->socketBio = BIO_new(BIO_s_simple_socket());

		if (!tcp->socketBio)
			return FALSE;

		BIO_set_fd(tcp->socketBio, tcp->sockfd, BIO_CLOSE);
	}
	else
	{
#ifdef HAVE_POLL_H
		struct pollfd pollfds;
#else
		fd_set cfds;
		struct timeval tv;
#endif

#ifdef NO_IPV6
		tcp->socketBio = BIO_new(BIO_s_connect());

		if (!tcp->socketBio)
			return FALSE;

		if (BIO_set_conn_hostname(tcp->socketBio, hostname) < 0 || BIO_set_conn_int_port(tcp->socketBio, &port) < 0)
			return FALSE;

		BIO_set_nbio(tcp->socketBio, 1);

		status = BIO_do_connect(tcp->socketBio);

		if ((status <= 0) && !BIO_should_retry(tcp->socketBio))
			return FALSE;

		tcp->sockfd = BIO_get_fd(tcp->socketBio, NULL);

		if (tcp->sockfd < 0)
			return FALSE;
#else /* NO_IPV6 */
		struct addrinfo hints = {0};
		struct addrinfo *result;
		struct addrinfo *tmp;
		char port_str[11];

		//ZeroMemory(&hints, sizeof(struct addrinfo));
		hints.ai_family = AF_UNSPEC;    /* Allow IPv4 or IPv6 */
		hints.ai_socktype = SOCK_STREAM;
		/*
		 * FIXME: the following is a nasty workaround. Find a cleaner way:
		 * Either set port manually afterwards or get it passed as string?
		 */
		sprintf_s(port_str, 11, "%u", port);

		status = getaddrinfo(hostname, port_str, &hints, &result);
		if (status) {
			fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status));
			return FALSE;
		}

		/* For now prefer IPv4 over IPv6. */
		tmp = result;
		if (tmp->ai_family == AF_INET6 && tmp->ai_next != 0)
		{
			while ((tmp = tmp->ai_next))
			{
				if (tmp->ai_family == AF_INET)
					break;
			}
			if (!tmp)
				tmp = result;
		}
		tcp->sockfd = socket(tmp->ai_family, tmp->ai_socktype, tmp->ai_protocol);

		if (tcp->sockfd  < 0) {
			freeaddrinfo(result);
			return FALSE;
		}

		if (connect(tcp->sockfd, tmp->ai_addr, tmp->ai_addrlen) < 0) {
			fprintf(stderr, "connect: %s\n", strerror(errno));
			freeaddrinfo(result);
			return FALSE;
		}
		freeaddrinfo(result);
		tcp->socketBio = BIO_new_socket(tcp->sockfd, BIO_NOCLOSE);

		/* TODO: make sure the handshake is done by querying the bio */
		//		if (BIO_should_retry(tcp->socketBio))
		//          return FALSE;
#endif /* NO_IPV6 */

		if (status <= 0)
		{
#ifdef HAVE_POLL_H
			pollfds.fd = tcp->sockfd;
			pollfds.events = POLLOUT;
			pollfds.revents = 0;
			do
			{
				status = poll(&pollfds, 1, timeout * 1000);
			}
			while ((status < 0) && (errno == EINTR));
#else
			FD_ZERO(&cfds);
			FD_SET(tcp->sockfd, &cfds);

			tv.tv_sec = timeout;
			tv.tv_usec = 0;

			status = _select(tcp->sockfd + 1, NULL, &cfds, NULL, &tv);
#endif
			if (status == 0)
			{
				return FALSE; /* timeout */
			}
		}

		(void)BIO_set_close(tcp->socketBio, BIO_NOCLOSE);
		BIO_free(tcp->socketBio);

		tcp->socketBio = BIO_new(BIO_s_simple_socket());

		if (!tcp->socketBio)
			return FALSE;

		BIO_set_fd(tcp->socketBio, tcp->sockfd, BIO_CLOSE);
	}

	SetEventFileDescriptor(tcp->event, tcp->sockfd);

	tcp_get_ip_address(tcp);
	tcp_get_mac_address(tcp);

	option_value = 1;
	option_len = sizeof(option_value);

	if (!tcp->ipcSocket)
	{
		if (setsockopt(tcp->sockfd, IPPROTO_TCP, TCP_NODELAY, (void*) &option_value, option_len) < 0)
			WLog_ERR(TAG,  "unable to set TCP_NODELAY");
	}

	/* receive buffer must be a least 32 K */
	if (getsockopt(tcp->sockfd, SOL_SOCKET, SO_RCVBUF, (void*) &option_value, &option_len) == 0)
	{
		if (option_value < (1024 * 32))
		{
			option_value = 1024 * 32;
			option_len = sizeof(option_value);

			if (setsockopt(tcp->sockfd, SOL_SOCKET, SO_RCVBUF, (void*) &option_value, option_len) < 0)
			{
				WLog_ERR(TAG,  "unable to set receive buffer len");
				return FALSE;
			}
		}
	}

	if (!tcp->ipcSocket)
	{
		if (!tcp_set_keep_alive_mode(tcp))
			return FALSE;
	}

	tcp->bufferedBio = BIO_new(BIO_s_buffered_socket());

	if (!tcp->bufferedBio)
		return FALSE;

	tcp->bufferedBio->ptr = tcp;

	tcp->bufferedBio = BIO_push(tcp->bufferedBio, tcp->socketBio);

	return TRUE;
}