[server,shadow] implement CheckPeerAcceptRestrictions

Implement a (optional) peer limitation check for shadow server.
with the command line option /max-connections:<number> the maximum
number of simultaneous connections can be limited.
This commit is contained in:
Armin Novak 2023-06-14 10:22:54 +02:00 committed by akallabeth
parent df3c78a91d
commit 4803ba046c
3 changed files with 34 additions and 0 deletions

View File

@ -171,6 +171,8 @@ extern "C"
char* PrivateKeyFile; char* PrivateKeyFile;
CRITICAL_SECTION lock; CRITICAL_SECTION lock;
freerdp_listener* listener; freerdp_listener* listener;
size_t maxClientsConnected;
}; };
struct rdp_shadow_surface struct rdp_shadow_surface

View File

@ -50,6 +50,8 @@ int main(int argc, char** argv)
"localhost" }, "localhost" },
{ "monitors", COMMAND_LINE_VALUE_OPTIONAL, "<0,1,2...>", NULL, NULL, -1, NULL, { "monitors", COMMAND_LINE_VALUE_OPTIONAL, "<0,1,2...>", NULL, NULL, -1, NULL,
"Select or list monitors" }, "Select or list monitors" },
{ "max-connections", COMMAND_LINE_VALUE_REQUIRED, "<number>", 0, NULL, -1, NULL,
"maximum connections allowed to server, 0 to deactivate" },
{ "rect", COMMAND_LINE_VALUE_REQUIRED, "<x,y,w,h>", NULL, NULL, -1, NULL, { "rect", COMMAND_LINE_VALUE_REQUIRED, "<x,y,w,h>", NULL, NULL, -1, NULL,
"Select rectangle within monitor to share" }, "Select rectangle within monitor to share" },
{ "auth", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, { "auth", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL,

View File

@ -214,6 +214,15 @@ int shadow_server_parse_command_line(rdpShadowServer* server, int argc, char** a
{ {
server->mayInteract = arg->Value ? TRUE : FALSE; server->mayInteract = arg->Value ? TRUE : FALSE;
} }
CommandLineSwitchCase(arg, "max-connections")
{
errno = 0;
unsigned long val = strtoul(arg->Value, NULL, 0);
if ((errno != 0) || (val > UINT32_MAX))
return -1;
server->maxClientsConnected = val;
}
CommandLineSwitchCase(arg, "rect") CommandLineSwitchCase(arg, "rect")
{ {
char* p; char* p;
@ -859,6 +868,26 @@ out_fail:
return ret; return ret;
} }
static BOOL shadow_server_check_peer_restrictions(freerdp_listener* listener)
{
WINPR_ASSERT(listener);
rdpShadowServer* server = (rdpShadowServer*)listener->info;
WINPR_ASSERT(server);
if (server->maxClientsConnected > 0)
{
const size_t count = ArrayList_Count(server->clients);
if (count >= server->maxClientsConnected)
{
WLog_WARN(TAG, "connection limit [%" PRIuz "] reached, discarding client",
server->maxClientsConnected);
return FALSE;
}
}
return TRUE;
}
int shadow_server_init(rdpShadowServer* server) int shadow_server_init(rdpShadowServer* server)
{ {
int status; int status;
@ -888,6 +917,7 @@ int shadow_server_init(rdpShadowServer* server)
goto fail; goto fail;
server->listener->info = (void*)server; server->listener->info = (void*)server;
server->listener->CheckPeerAcceptRestrictions = shadow_server_check_peer_restrictions;
server->listener->PeerAccepted = shadow_client_accepted; server->listener->PeerAccepted = shadow_client_accepted;
server->subsystem = shadow_subsystem_new(); server->subsystem = shadow_subsystem_new();