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; }
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; }
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; }
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; }
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; }