|
Packit |
1fb8d4 |
/**
|
|
Packit |
1fb8d4 |
* FreeRDP: A Remote Desktop Protocol Implementation
|
|
Packit |
1fb8d4 |
* RDP Server Listener
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
* Copyright 2011 Vic Lee
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
Packit |
1fb8d4 |
* you may not use this file except in compliance with the License.
|
|
Packit |
1fb8d4 |
* You may obtain a copy of the License at
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
* http://www.apache.org/licenses/LICENSE-2.0
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
* Unless required by applicable law or agreed to in writing, software
|
|
Packit |
1fb8d4 |
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
Packit |
1fb8d4 |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
Packit |
1fb8d4 |
* See the License for the specific language governing permissions and
|
|
Packit |
1fb8d4 |
* limitations under the License.
|
|
Packit |
1fb8d4 |
*/
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
1fb8d4 |
#include "config.h"
|
|
Packit |
1fb8d4 |
#endif
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#include <stdio.h>
|
|
Packit |
1fb8d4 |
#include <stdlib.h>
|
|
Packit |
1fb8d4 |
#include <string.h>
|
|
Packit |
1fb8d4 |
#include <fcntl.h>
|
|
Packit |
1fb8d4 |
#include <errno.h>
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#include <winpr/crt.h>
|
|
Packit |
1fb8d4 |
#include <winpr/windows.h>
|
|
Packit |
1fb8d4 |
#include <freerdp/log.h>
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#ifndef _WIN32
|
|
Packit |
1fb8d4 |
#include <netdb.h>
|
|
Packit |
1fb8d4 |
#include <unistd.h>
|
|
Packit |
1fb8d4 |
#include <sys/un.h>
|
|
Packit |
1fb8d4 |
#include <sys/ioctl.h>
|
|
Packit |
1fb8d4 |
#include <sys/socket.h>
|
|
Packit |
1fb8d4 |
#include <arpa/inet.h>
|
|
Packit |
1fb8d4 |
#include <netinet/in.h>
|
|
Packit |
1fb8d4 |
#include <net/if.h>
|
|
Packit |
1fb8d4 |
#endif
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#include <winpr/handle.h>
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#include "listener.h"
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#define TAG FREERDP_TAG("core.listener")
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static BOOL freerdp_listener_open(freerdp_listener* instance, const char* bind_address, UINT16 port)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
int ai_flags = 0;
|
|
Packit |
1fb8d4 |
int status;
|
|
Packit |
1fb8d4 |
int sockfd;
|
|
Packit |
1fb8d4 |
char addr[64];
|
|
Packit |
1fb8d4 |
void* sin_addr;
|
|
Packit |
1fb8d4 |
int option_value;
|
|
Packit |
1fb8d4 |
struct addrinfo* ai;
|
|
Packit |
1fb8d4 |
struct addrinfo* res;
|
|
Packit Service |
5a9772 |
rdpListener* listener = (rdpListener*)instance->listener;
|
|
Packit |
1fb8d4 |
#ifdef _WIN32
|
|
Packit |
1fb8d4 |
u_long arg;
|
|
Packit |
1fb8d4 |
#endif
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!bind_address)
|
|
Packit |
1fb8d4 |
ai_flags = AI_PASSIVE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
res = freerdp_tcp_resolve_host(bind_address, port, ai_flags);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!res)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
for (ai = res; ai && (listener->num_sockfds < 5); ai = ai->ai_next)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if ((ai->ai_family != AF_INET) && (ai->ai_family != AF_INET6))
|
|
Packit |
1fb8d4 |
continue;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (listener->num_sockfds == MAX_LISTENER_HANDLES)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
WLog_ERR(TAG, "too many listening sockets");
|
|
Packit |
1fb8d4 |
continue;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (sockfd == -1)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
WLog_ERR(TAG, "socket");
|
|
Packit |
1fb8d4 |
continue;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (ai->ai_family == AF_INET)
|
|
Packit Service |
5a9772 |
sin_addr = &(((struct sockaddr_in*)ai->ai_addr)->sin_addr);
|
|
Packit |
1fb8d4 |
else
|
|
Packit Service |
5a9772 |
sin_addr = &(((struct sockaddr_in6*)ai->ai_addr)->sin6_addr);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
inet_ntop(ai->ai_family, sin_addr, addr, sizeof(addr));
|
|
Packit |
1fb8d4 |
option_value = 1;
|
|
Packit |
1fb8d4 |
|
|
Packit Service |
5a9772 |
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void*)&option_value,
|
|
Packit Service |
5a9772 |
sizeof(option_value)) == -1)
|
|
Packit |
1fb8d4 |
WLog_ERR(TAG, "setsockopt");
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#ifndef _WIN32
|
|
Packit |
1fb8d4 |
fcntl(sockfd, F_SETFL, O_NONBLOCK);
|
|
Packit |
1fb8d4 |
#else
|
|
Packit |
1fb8d4 |
arg = 1;
|
|
Packit |
1fb8d4 |
ioctlsocket(sockfd, FIONBIO, &arg;;
|
|
Packit |
1fb8d4 |
#endif
|
|
Packit Service |
5a9772 |
status = _bind((SOCKET)sockfd, ai->ai_addr, ai->ai_addrlen);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (status != 0)
|
|
Packit |
1fb8d4 |
{
|
|
Packit Service |
5a9772 |
closesocket((SOCKET)sockfd);
|
|
Packit |
1fb8d4 |
continue;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit Service |
5a9772 |
status = _listen((SOCKET)sockfd, 10);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (status != 0)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
WLog_ERR(TAG, "listen");
|
|
Packit Service |
5a9772 |
closesocket((SOCKET)sockfd);
|
|
Packit |
1fb8d4 |
continue;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
/* FIXME: these file descriptors do not work on Windows */
|
|
Packit |
1fb8d4 |
listener->sockfds[listener->num_sockfds] = sockfd;
|
|
Packit |
1fb8d4 |
listener->events[listener->num_sockfds] = WSACreateEvent();
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!listener->events[listener->num_sockfds])
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
listener->num_sockfds = 0;
|
|
Packit |
1fb8d4 |
break;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit Service |
5a9772 |
WSAEventSelect(sockfd, listener->events[listener->num_sockfds],
|
|
Packit Service |
5a9772 |
FD_READ | FD_ACCEPT | FD_CLOSE);
|
|
Packit |
1fb8d4 |
listener->num_sockfds++;
|
|
Packit Service |
5a9772 |
WLog_INFO(TAG, "Listening on [%s]:%d", addr, port);
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
freeaddrinfo(res);
|
|
Packit |
1fb8d4 |
return (listener->num_sockfds > 0 ? TRUE : FALSE);
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static BOOL freerdp_listener_open_local(freerdp_listener* instance, const char* path)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
#ifndef _WIN32
|
|
Packit |
1fb8d4 |
int status;
|
|
Packit |
1fb8d4 |
int sockfd;
|
|
Packit |
1fb8d4 |
struct sockaddr_un addr = { 0 };
|
|
Packit Service |
5a9772 |
rdpListener* listener = (rdpListener*)instance->listener;
|
|
Packit |
1fb8d4 |
HANDLE hevent;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (listener->num_sockfds == MAX_LISTENER_HANDLES)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
WLog_ERR(TAG, "too many listening sockets");
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (sockfd == -1)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
WLog_ERR(TAG, "socket");
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
fcntl(sockfd, F_SETFL, O_NONBLOCK);
|
|
Packit |
1fb8d4 |
addr.sun_family = AF_UNIX;
|
|
Packit |
1fb8d4 |
strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
|
|
Packit |
1fb8d4 |
unlink(path);
|
|
Packit Service |
5a9772 |
status = _bind(sockfd, (struct sockaddr*)&addr, sizeof(addr));
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (status != 0)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
WLog_ERR(TAG, "bind");
|
|
Packit Service |
5a9772 |
closesocket((SOCKET)sockfd);
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
status = _listen(sockfd, 10);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (status != 0)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
WLog_ERR(TAG, "listen");
|
|
Packit Service |
5a9772 |
closesocket((SOCKET)sockfd);
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
hevent = CreateFileDescriptorEvent(NULL, FALSE, FALSE, sockfd, WINPR_FD_READ);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!hevent)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
WLog_ERR(TAG, "failed to create sockfd event");
|
|
Packit Service |
5a9772 |
closesocket((SOCKET)sockfd);
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
listener->sockfds[listener->num_sockfds] = sockfd;
|
|
Packit |
1fb8d4 |
listener->events[listener->num_sockfds] = hevent;
|
|
Packit |
1fb8d4 |
listener->num_sockfds++;
|
|
Packit |
1fb8d4 |
WLog_INFO(TAG, "Listening on socket %s.", addr.sun_path);
|
|
Packit |
1fb8d4 |
return TRUE;
|
|
Packit |
1fb8d4 |
#else
|
|
Packit |
1fb8d4 |
return TRUE;
|
|
Packit |
1fb8d4 |
#endif
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static BOOL freerdp_listener_open_from_socket(freerdp_listener* instance, int fd)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
#ifndef _WIN32
|
|
Packit Service |
5a9772 |
rdpListener* listener = (rdpListener*)instance->listener;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (listener->num_sockfds == MAX_LISTENER_HANDLES)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
WLog_ERR(TAG, "too many listening sockets");
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
listener->sockfds[listener->num_sockfds] = fd;
|
|
Packit |
1fb8d4 |
listener->events[listener->num_sockfds] =
|
|
Packit |
1fb8d4 |
CreateFileDescriptorEvent(NULL, FALSE, FALSE, fd, WINPR_FD_READ);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!listener->events[listener->num_sockfds])
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
listener->num_sockfds++;
|
|
Packit |
1fb8d4 |
WLog_INFO(TAG, "Listening on socket %d.", fd);
|
|
Packit |
1fb8d4 |
return TRUE;
|
|
Packit |
1fb8d4 |
#else
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
#endif
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static void freerdp_listener_close(freerdp_listener* instance)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
int i;
|
|
Packit Service |
5a9772 |
rdpListener* listener = (rdpListener*)instance->listener;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
for (i = 0; i < listener->num_sockfds; i++)
|
|
Packit |
1fb8d4 |
{
|
|
Packit Service |
5a9772 |
closesocket((SOCKET)listener->sockfds[i]);
|
|
Packit |
1fb8d4 |
CloseHandle(listener->events[i]);
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
listener->num_sockfds = 0;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static BOOL freerdp_listener_get_fds(freerdp_listener* instance, void** rfds, int* rcount)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
int index;
|
|
Packit Service |
5a9772 |
rdpListener* listener = (rdpListener*)instance->listener;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (listener->num_sockfds < 1)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
for (index = 0; index < listener->num_sockfds; index++)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
rfds[*rcount] = (void*)(long)(listener->sockfds[index]);
|
|
Packit |
1fb8d4 |
(*rcount)++;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return TRUE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit Service |
5a9772 |
static DWORD freerdp_listener_get_event_handles(freerdp_listener* instance, HANDLE* events,
|
|
Packit Service |
5a9772 |
DWORD nCount)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
int index;
|
|
Packit Service |
5a9772 |
rdpListener* listener = (rdpListener*)instance->listener;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (listener->num_sockfds < 1)
|
|
Packit |
1fb8d4 |
return 0;
|
|
Packit |
1fb8d4 |
|
|
Packit Service |
5a9772 |
if (listener->num_sockfds > (INT64)nCount)
|
|
Packit |
1fb8d4 |
return 0;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
for (index = 0; index < listener->num_sockfds; index++)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
events[index] = listener->events[index];
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return listener->num_sockfds;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static BOOL freerdp_listener_check_fds(freerdp_listener* instance)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
int i;
|
|
Packit |
1fb8d4 |
void* sin_addr;
|
|
Packit |
1fb8d4 |
int peer_sockfd;
|
|
Packit |
1fb8d4 |
freerdp_peer* client = NULL;
|
|
Packit |
1fb8d4 |
int peer_addr_size;
|
|
Packit |
1fb8d4 |
struct sockaddr_storage peer_addr;
|
|
Packit Service |
5a9772 |
rdpListener* listener = (rdpListener*)instance->listener;
|
|
Packit |
1fb8d4 |
static const BYTE localhost6_bytes[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
|
|
Packit |
1fb8d4 |
BOOL peer_accepted;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (listener->num_sockfds < 1)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
for (i = 0; i < listener->num_sockfds; i++)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
WSAResetEvent(listener->events[i]);
|
|
Packit |
1fb8d4 |
peer_addr_size = sizeof(peer_addr);
|
|
Packit Service |
5a9772 |
peer_sockfd = _accept(listener->sockfds[i], (struct sockaddr*)&peer_addr, &peer_addr_size);
|
|
Packit |
1fb8d4 |
peer_accepted = FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (peer_sockfd == -1)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
#ifdef _WIN32
|
|
Packit |
1fb8d4 |
int wsa_error = WSAGetLastError();
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
/* No data available */
|
|
Packit |
1fb8d4 |
if (wsa_error == WSAEWOULDBLOCK)
|
|
Packit |
1fb8d4 |
continue;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#else
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (errno == EAGAIN || errno == EWOULDBLOCK)
|
|
Packit |
1fb8d4 |
continue;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#endif
|
|
Packit |
1fb8d4 |
WLog_DBG(TAG, "accept");
|
|
Packit |
1fb8d4 |
free(client);
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
client = freerdp_peer_new(peer_sockfd);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!client)
|
|
Packit |
1fb8d4 |
{
|
|
Packit Service |
5a9772 |
closesocket((SOCKET)peer_sockfd);
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
sin_addr = NULL;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (peer_addr.ss_family == AF_INET)
|
|
Packit |
1fb8d4 |
{
|
|
Packit Service |
5a9772 |
sin_addr = &(((struct sockaddr_in*)&peer_addr)->sin_addr);
|
|
Packit |
1fb8d4 |
|
|
Packit Service |
5a9772 |
if ((*(UINT32*)sin_addr) == 0x0100007f)
|
|
Packit |
1fb8d4 |
client->local = TRUE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
else if (peer_addr.ss_family == AF_INET6)
|
|
Packit |
1fb8d4 |
{
|
|
Packit Service |
5a9772 |
sin_addr = &(((struct sockaddr_in6*)&peer_addr)->sin6_addr);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (memcmp(sin_addr, localhost6_bytes, 16) == 0)
|
|
Packit |
1fb8d4 |
client->local = TRUE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#ifndef _WIN32
|
|
Packit |
1fb8d4 |
else if (peer_addr.ss_family == AF_UNIX)
|
|
Packit |
1fb8d4 |
client->local = TRUE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#endif
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (sin_addr)
|
|
Packit |
1fb8d4 |
inet_ntop(peer_addr.ss_family, sin_addr, client->hostname, sizeof(client->hostname));
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
IFCALLRET(instance->PeerAccepted, peer_accepted, instance, client);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!peer_accepted)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
WLog_ERR(TAG, "PeerAccepted callback failed");
|
|
Packit Service |
5a9772 |
closesocket((SOCKET)peer_sockfd);
|
|
Packit |
1fb8d4 |
freerdp_peer_free(client);
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return TRUE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
freerdp_listener* freerdp_listener_new(void)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
freerdp_listener* instance;
|
|
Packit |
1fb8d4 |
rdpListener* listener;
|
|
Packit Service |
5a9772 |
instance = (freerdp_listener*)calloc(1, sizeof(freerdp_listener));
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!instance)
|
|
Packit |
1fb8d4 |
return NULL;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
instance->Open = freerdp_listener_open;
|
|
Packit |
1fb8d4 |
instance->OpenLocal = freerdp_listener_open_local;
|
|
Packit |
1fb8d4 |
instance->OpenFromSocket = freerdp_listener_open_from_socket;
|
|
Packit |
1fb8d4 |
instance->GetFileDescriptor = freerdp_listener_get_fds;
|
|
Packit |
1fb8d4 |
instance->GetEventHandles = freerdp_listener_get_event_handles;
|
|
Packit |
1fb8d4 |
instance->CheckFileDescriptor = freerdp_listener_check_fds;
|
|
Packit |
1fb8d4 |
instance->Close = freerdp_listener_close;
|
|
Packit Service |
5a9772 |
listener = (rdpListener*)calloc(1, sizeof(rdpListener));
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!listener)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
free(instance);
|
|
Packit |
1fb8d4 |
return NULL;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
listener->instance = instance;
|
|
Packit Service |
5a9772 |
instance->listener = (void*)listener;
|
|
Packit |
1fb8d4 |
return instance;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
void freerdp_listener_free(freerdp_listener* instance)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (instance)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
free(instance->listener);
|
|
Packit |
1fb8d4 |
free(instance);
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|