示例#1
0
文件: winsock.c 项目: anirnet/FreeRDP
int WSAEventSelect(SOCKET s, WSAEVENT hEventObject, LONG lNetworkEvents)
{
	u_long arg = 1;

	if (_ioctlsocket(s, FIONBIO, &arg) != 0)
		return SOCKET_ERROR;

	if (SetEventFileDescriptor(hEventObject, s) < 0)
		return SOCKET_ERROR;

	return 0;
}
bool SocketServer::openListeningPort() {
	// read parameters
	short socket_port = port;

	// prepare socket
	int l_len;
	l_len = sizeof( struct sockaddr_in );
	memset( &listen_inet , 0 , l_len );
	listen_inet.sin_port = htons( ( unsigned short )socket_port );

	/* calculate itself address */
	listen_inet.sin_family = AF_INET;
	listen_inet.sin_addr.s_addr = INADDR_ANY;

	unsigned long l_ok = 1;
	listenSocket = socket( AF_INET , SOCK_STREAM , 0 );
	if( listenSocket == INVALID_SOCKET )
		l_ok = 0;

	if( l_ok )
		if( bind( listenSocket , ( struct sockaddr * )&listen_inet , l_len ) )
			l_ok = 0;

	// options
	BOOL option = FALSE;
	if( l_ok )
		if( setsockopt( listenSocket , SOL_SOCKET , SO_KEEPALIVE , ( const char * )&option , sizeof( BOOL ) ) )
			l_ok = 0;

	/* set socket to non-blocking mode */
	if( l_ok )
		if( _ioctlsocket( listenSocket , FIONBIO , &l_ok ) )
			l_ok = 0;

	// set listening mode
	if( l_ok )
		if( listen( listenSocket , SOMAXCONN ) )
			l_ok = 0;

	if( !l_ok )
		return( false );

	// start listening thread
	ThreadService *ts = ThreadService::getService();
	listenThread = ts -> runThread( SocketListener::getName() , this , ( ObjectThreadFunction )&SocketServer::threadConnectFunction , NULL );
	
	String msg = "openListeningPort: started listener=" + SocketListener::getName() + " on address=" + getAddress( &listen_inet );
	logger.logInfo( msg );

	return( true );
}
void SocketServer::performConnect() {
	bool l_error;
	if( !SocketProtocol::waitSocketDataInfinite( listenSocket , l_error ) ) {
		continueConnecting = false;
		return;
	}

	// connect request received
	struct sockaddr_in clientAddress;
	memset( &clientAddress , 0 , sizeof( struct sockaddr_in ) );
	clientAddress.sin_family = AF_INET;

	int l_len = sizeof( struct sockaddr_in );
	SOCKET clientSocket = accept( listenSocket , ( struct sockaddr * )&clientAddress , &l_len );

	if( clientSocket == INVALID_SOCKET ) {
		continueConnecting = false;
		logger.logError( "performConnect: accept returned INVALID_SOCKET" );
		return;
	}

	/* set non-blocking */
	unsigned long l_ok = 1;
	_ioctlsocket( clientSocket , FIONBIO , &l_ok );
	/* set linger */
	struct linger l_linger;
	l_linger.l_onoff = 1;
	l_linger.l_linger = 0;

	setsockopt( clientSocket , SOL_SOCKET , SO_LINGER , ( char * )&l_linger , sizeof( struct linger ) );

	// start connection thread
	if( !startConnection( clientSocket , &clientAddress ) ) {
		continueConnecting = false;
		logger.logError( "performConnect: cannot start client thread" );
		return;
	}
}
示例#4
0
文件: tcp.c 项目: kdienes/FreeRDP
static int freerdp_tcp_connect_multi(rdpContext* context, char** hostnames,
				     UINT32* ports, int count, int port,
				     int timeout)
{
	int index;
	int sindex;
	int status;
	SOCKET sockfd = -1;
	SOCKET* sockfds;
	HANDLE* events;
	DWORD waitStatus;
	char port_str[16];
	struct addrinfo hints;
	struct addrinfo* addr;
	struct addrinfo* result;
	struct addrinfo** addrs;
	struct addrinfo** results;

	sprintf_s(port_str, sizeof(port_str) - 1, "%d", port);

	sockfds = (SOCKET*) calloc(count, sizeof(SOCKET));
	events = (HANDLE*) calloc(count + 1, sizeof(HANDLE));
	addrs = (struct addrinfo**) calloc(count, sizeof(struct addrinfo*));
	results = (struct addrinfo**) calloc(count, sizeof(struct addrinfo*));

	if (!sockfds || !events || !addrs || !results)
	{
		free(sockfds);
		free(events);
		free(addrs);
		free(results);
		return -1;
	}

	for (index = 0; index < count; index++)
	{
		ZeroMemory(&hints, sizeof(hints));
		hints.ai_family = AF_UNSPEC;
		hints.ai_socktype = SOCK_STREAM;

		if (ports)
			sprintf_s(port_str, sizeof(port_str) - 1, "%"PRIu32"", ports[index]);

		status = getaddrinfo(hostnames[index], port_str, &hints, &result);

		if (status)
		{
			continue;
		}

		addr = result;

		if ((addr->ai_family == AF_INET6) && (addr->ai_next != 0))
		{
			while ((addr = addr->ai_next))
			{
				if (addr->ai_family == AF_INET)
					break;
			}

			if (!addr)
				addr = result;
		}

		sockfds[index] = _socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);

		if (sockfds[index] == INVALID_SOCKET)
		{
			freeaddrinfo(result);
			sockfds[index] = 0;
			continue;
		}

		addrs[index] = addr;
		results[index] = result;
	}

	for (index = 0; index < count; index++)
	{
		if (!sockfds[index])
			continue;

		sockfd = sockfds[index];
		addr = addrs[index];

		/* set socket in non-blocking mode */
		events[index] = WSACreateEvent();
		if (!events[index])
		{
			WLog_ERR(TAG, "WSACreateEvent returned 0x%08X", WSAGetLastError());
			continue;
		}

		if (WSAEventSelect(sockfd, events[index], FD_READ | FD_WRITE | FD_CONNECT | FD_CLOSE))
		{
			WLog_ERR(TAG, "WSAEventSelect returned 0x%08X", WSAGetLastError());
			continue;
		}

		/* non-blocking tcp connect */

		status = _connect(sockfd, addr->ai_addr, addr->ai_addrlen);

		if (status >= 0)
		{
			/* connection success */
			break;
		}
	}

	events[count] = context->abortEvent;

	waitStatus = WaitForMultipleObjects(count + 1, events, FALSE, timeout * 1000);

	sindex = waitStatus - WAIT_OBJECT_0;

	for (index = 0; index < count; index++)
	{
		u_long arg = 0;

		if (!sockfds[index])
			continue;

		sockfd = sockfds[index];

		/* set socket in blocking mode */
		if (WSAEventSelect(sockfd, NULL, 0))
		{
			WLog_ERR(TAG, "WSAEventSelect returned 0x%08X", WSAGetLastError());
			continue;
		}

		if (_ioctlsocket(sockfd, FIONBIO, &arg))
		{
			WLog_ERR(TAG, "_ioctlsocket failed");
		}
	}

	if ((sindex >= 0) && (sindex < count))
	{
		sockfd = sockfds[sindex];
	}

	if (sindex == count)
		freerdp_set_last_error(context, FREERDP_ERROR_CONNECT_CANCELLED);

	for (index = 0; index < count; index++)
	{
		if (results[index])
			freeaddrinfo(results[index]);
		CloseHandle(events[index]);
	}

	free(addrs);
	free(results);
	free(sockfds);
	free(events);

	return sockfd;
}
示例#5
0
文件: tcp.c 项目: kdienes/FreeRDP
static BOOL freerdp_tcp_connect_timeout(rdpContext* context, int sockfd,
					struct sockaddr* addr,
					socklen_t addrlen, int timeout)
{
	HANDLE handles[2];
	int status = 0;
	int count = 0;
	u_long arg = 0;
	DWORD tout = (timeout) ? timeout * 1000 : INFINITE;

	handles[count] = CreateEvent(NULL, TRUE, FALSE, NULL);
	if (!handles[count])
		return FALSE;

	status = WSAEventSelect(sockfd, handles[count++], FD_READ | FD_WRITE | FD_CONNECT | FD_CLOSE);
	if (status < 0)
	{
		WLog_ERR(TAG, "WSAEventSelect failed with %d", WSAGetLastError());
		return FALSE;
	}

	handles[count++] = context->abortEvent;

	status = _connect(sockfd, addr, addrlen);
	if (status < 0)
	{
		status = WSAGetLastError();
		switch(status)
		{
			case WSAEINPROGRESS:
			case WSAEWOULDBLOCK:
				break;
			default:
				return FALSE;
		}
	}

	status = WaitForMultipleObjects(count, handles, FALSE, tout);
	if (WAIT_OBJECT_0 != status)
	{
		if (status == WAIT_OBJECT_0 + 1)
			freerdp_set_last_error(context, FREERDP_ERROR_CONNECT_CANCELLED);

		return FALSE;
	}

	status = recv(sockfd, NULL, 0, 0);
	if (status == SOCKET_ERROR)
	{
		if (WSAGetLastError() == WSAECONNRESET)
			return FALSE;
	}

	status = WSAEventSelect(sockfd, handles[0], 0);
	CloseHandle(handles[0]);

	if (status < 0)
	{
		WLog_ERR(TAG, "WSAEventSelect failed with %d", WSAGetLastError());
		return FALSE;
	}

	if (_ioctlsocket(sockfd, FIONBIO, &arg) != 0)
		return FALSE;

	return TRUE;
}