mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-10-29 05:40:23 -04:00
limit the number of concurrent connections for all four protocols
kick a client if it doesn't authenticate within 5s on ESD and native protocol git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@292 fefdeb5f-60dc-0310-8127-8f9354f1896f
This commit is contained in:
parent
c57d5deef6
commit
eef235d879
4 changed files with 104 additions and 12 deletions
|
|
@ -29,6 +29,10 @@
|
|||
#include "protocol-cli.h"
|
||||
#include "cli.h"
|
||||
#include "xmalloc.h"
|
||||
#include "log.h"
|
||||
|
||||
/* Don't allow more than this many concurrent connections */
|
||||
#define MAX_CONNECTIONS 10
|
||||
|
||||
struct pa_protocol_cli {
|
||||
struct pa_module *module;
|
||||
|
|
@ -49,6 +53,12 @@ static void on_connection(struct pa_socket_server*s, struct pa_iochannel *io, vo
|
|||
struct pa_cli *c;
|
||||
assert(s && io && p);
|
||||
|
||||
if (pa_idxset_ncontents(p->connections)+1 > MAX_CONNECTIONS) {
|
||||
pa_log(__FILE__": Warning! Too many connections (%u), dropping incoming connection.\n", MAX_CONNECTIONS);
|
||||
pa_iochannel_free(io);
|
||||
return;
|
||||
}
|
||||
|
||||
c = pa_cli_new(p->core, io, p->module);
|
||||
assert(c);
|
||||
pa_cli_set_eof_callback(c, cli_eof_cb, p);
|
||||
|
|
|
|||
|
|
@ -46,6 +46,12 @@
|
|||
#include "xmalloc.h"
|
||||
#include "log.h"
|
||||
|
||||
/* Don't accept more connection than this */
|
||||
#define MAX_CONNECTIONS 10
|
||||
|
||||
/* Kick a client if it doesn't authenticate within this time */
|
||||
#define AUTH_TIMEOUT 5
|
||||
|
||||
#define DEFAULT_COOKIE_FILE ".esd_auth"
|
||||
|
||||
#define PLAYBACK_BUFFER_SECONDS (.5)
|
||||
|
|
@ -87,6 +93,8 @@ struct connection {
|
|||
char *name;
|
||||
struct pa_sample_spec sample_spec;
|
||||
} scache;
|
||||
|
||||
struct pa_time_event *auth_timeout_event;
|
||||
};
|
||||
|
||||
struct pa_protocol_esound {
|
||||
|
|
@ -202,6 +210,9 @@ static void connection_free(struct connection *c) {
|
|||
if (c->scache.memchunk.memblock)
|
||||
pa_memblock_unref(c->scache.memchunk.memblock);
|
||||
pa_xfree(c->scache.name);
|
||||
|
||||
if (c->auth_timeout_event)
|
||||
c->protocol->core->mainloop->time_free(c->auth_timeout_event);
|
||||
|
||||
pa_xfree(c);
|
||||
}
|
||||
|
|
@ -256,6 +267,8 @@ static int esd_proto_connect(struct connection *c, esd_proto_t request, const vo
|
|||
}
|
||||
|
||||
c->authorized = 1;
|
||||
if (c->auth_timeout_event)
|
||||
c->protocol->core->mainloop->time_free(c->auth_timeout_event);
|
||||
}
|
||||
|
||||
ekey = *(uint32_t*)((uint8_t*) data+ESD_KEY_LEN);
|
||||
|
|
@ -1003,25 +1016,40 @@ static pa_usec_t source_output_get_latency_cb(struct pa_source_output *o) {
|
|||
|
||||
/*** socket server callback ***/
|
||||
|
||||
static void auth_timeout(struct pa_mainloop_api*m, struct pa_time_event *e, const struct timeval *tv, void *userdata) {
|
||||
struct connection *c = userdata;
|
||||
assert(m && tv && c && c->auth_timeout_event == e);
|
||||
|
||||
if (!c->authorized)
|
||||
connection_free(c);
|
||||
}
|
||||
|
||||
static void on_connection(struct pa_socket_server*s, struct pa_iochannel *io, void *userdata) {
|
||||
struct connection *c;
|
||||
struct pa_protocol_esound *p = userdata;
|
||||
char cname[256];
|
||||
assert(s && io && userdata);
|
||||
assert(s && io && p);
|
||||
|
||||
if (pa_idxset_ncontents(p->connections)+1 > MAX_CONNECTIONS) {
|
||||
pa_log(__FILE__": Warning! Too many connections (%u), dropping incoming connection.\n", MAX_CONNECTIONS);
|
||||
pa_iochannel_free(io);
|
||||
return;
|
||||
}
|
||||
|
||||
c = pa_xmalloc(sizeof(struct connection));
|
||||
c->protocol = userdata;
|
||||
c->protocol = p;
|
||||
c->io = io;
|
||||
pa_iochannel_set_callback(c->io, io_callback, c);
|
||||
|
||||
pa_iochannel_socket_peer_to_string(io, cname, sizeof(cname));
|
||||
assert(c->protocol->core);
|
||||
c->client = pa_client_new(c->protocol->core, "ESOUND", cname);
|
||||
assert(p->core);
|
||||
c->client = pa_client_new(p->core, "ESOUND", cname);
|
||||
assert(c->client);
|
||||
c->client->owner = c->protocol->module;
|
||||
c->client->owner = p->module;
|
||||
c->client->kill = client_kill_cb;
|
||||
c->client->userdata = c;
|
||||
|
||||
c->authorized = c->protocol->public;
|
||||
c->authorized = p->public;
|
||||
c->swap_byte_order = 0;
|
||||
c->dead = 0;
|
||||
|
||||
|
|
@ -1047,19 +1075,27 @@ static void on_connection(struct pa_socket_server*s, struct pa_iochannel *io, vo
|
|||
c->scache.memchunk.length = c->scache.memchunk.index = 0;
|
||||
c->scache.memchunk.memblock = NULL;
|
||||
c->scache.name = NULL;
|
||||
|
||||
c->defer_event = c->protocol->core->mainloop->defer_new(c->protocol->core->mainloop, defer_callback, c);
|
||||
assert(c->defer_event);
|
||||
c->protocol->core->mainloop->defer_enable(c->defer_event, 0);
|
||||
|
||||
pa_idxset_put(c->protocol->connections, c, &c->index);
|
||||
if (!c->authorized) {
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
tv.tv_sec += AUTH_TIMEOUT;
|
||||
c->auth_timeout_event = p->core->mainloop->time_new(p->core->mainloop, &tv, auth_timeout, c);
|
||||
} else
|
||||
c->auth_timeout_event = NULL;
|
||||
|
||||
c->defer_event = p->core->mainloop->defer_new(p->core->mainloop, defer_callback, c);
|
||||
assert(c->defer_event);
|
||||
p->core->mainloop->defer_enable(c->defer_event, 0);
|
||||
|
||||
pa_idxset_put(p->connections, c, &c->index);
|
||||
}
|
||||
|
||||
/*** entry points ***/
|
||||
|
||||
struct pa_protocol_esound* pa_protocol_esound_new(struct pa_core*core, struct pa_socket_server *server, struct pa_module *m, struct pa_modargs *ma) {
|
||||
struct pa_protocol_esound *p;
|
||||
int public;
|
||||
int public = 0;
|
||||
assert(core && server && ma);
|
||||
|
||||
p = pa_xmalloc(sizeof(struct pa_protocol_esound));
|
||||
|
|
|
|||
|
|
@ -50,6 +50,12 @@
|
|||
#include "strlist.h"
|
||||
#include "props.h"
|
||||
|
||||
/* Kick a client if it doesn't authenticate within this time */
|
||||
#define AUTH_TIMEOUT 5
|
||||
|
||||
/* Don't accept more connection than this */
|
||||
#define MAX_CONNECTIONS 10
|
||||
|
||||
struct connection;
|
||||
struct pa_protocol_native;
|
||||
|
||||
|
|
@ -100,6 +106,7 @@ struct connection {
|
|||
struct pa_idxset *record_streams, *output_streams;
|
||||
uint32_t rrobin_index;
|
||||
struct pa_subscription *subscription;
|
||||
struct pa_time_event *auth_timeout_event;
|
||||
};
|
||||
|
||||
struct pa_protocol_native {
|
||||
|
|
@ -374,6 +381,9 @@ static void connection_free(struct connection *c) {
|
|||
|
||||
if (c->subscription)
|
||||
pa_subscription_free(c->subscription);
|
||||
|
||||
if (c->auth_timeout_event)
|
||||
c->protocol->core->mainloop->time_free(c->auth_timeout_event);
|
||||
|
||||
pa_xfree(c);
|
||||
}
|
||||
|
|
@ -746,6 +756,10 @@ static void command_auth(struct pa_pdispatch *pd, uint32_t command, uint32_t tag
|
|||
}
|
||||
|
||||
c->authorized = 1;
|
||||
if (c->auth_timeout_event) {
|
||||
c->protocol->core->mainloop->time_free(c->auth_timeout_event);
|
||||
c->auth_timeout_event = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
pa_pstream_send_simple_ack(c->pstream, tag);
|
||||
|
|
@ -1973,14 +1987,37 @@ static void client_kill_cb(struct pa_client *c) {
|
|||
|
||||
/*** socket server callbacks ***/
|
||||
|
||||
static void auth_timeout(struct pa_mainloop_api*m, struct pa_time_event *e, const struct timeval *tv, void *userdata) {
|
||||
struct connection *c = userdata;
|
||||
assert(m && tv && c && c->auth_timeout_event == e);
|
||||
|
||||
if (!c->authorized)
|
||||
connection_free(c);
|
||||
}
|
||||
|
||||
static void on_connection(struct pa_socket_server*s, struct pa_iochannel *io, void *userdata) {
|
||||
struct pa_protocol_native *p = userdata;
|
||||
struct connection *c;
|
||||
assert(io && p);
|
||||
|
||||
if (pa_idxset_ncontents(p->connections)+1 > MAX_CONNECTIONS) {
|
||||
pa_log(__FILE__": Warning! Too many connections (%u), dropping incoming connection.\n", MAX_CONNECTIONS);
|
||||
pa_iochannel_free(io);
|
||||
return;
|
||||
}
|
||||
|
||||
c = pa_xmalloc(sizeof(struct connection));
|
||||
|
||||
c->authorized =!! p->public;
|
||||
|
||||
if (!c->authorized) {
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
tv.tv_sec += AUTH_TIMEOUT;
|
||||
c->auth_timeout_event = p->core->mainloop->time_new(p->core->mainloop, &tv, auth_timeout, c);
|
||||
} else
|
||||
c->auth_timeout_event = NULL;
|
||||
|
||||
c->protocol = p;
|
||||
assert(p->core);
|
||||
c->client = pa_client_new(p->core, "NATIVE", "Client");
|
||||
|
|
|
|||
|
|
@ -39,6 +39,9 @@
|
|||
#include "xmalloc.h"
|
||||
#include "log.h"
|
||||
|
||||
/* Don't allow more than this many concurrent connections */
|
||||
#define MAX_CONNECTIONS 10
|
||||
|
||||
struct connection {
|
||||
struct pa_protocol_simple *protocol;
|
||||
struct pa_iochannel *io;
|
||||
|
|
@ -287,6 +290,12 @@ static void on_connection(struct pa_socket_server*s, struct pa_iochannel *io, vo
|
|||
char cname[256];
|
||||
assert(s && io && p);
|
||||
|
||||
if (pa_idxset_ncontents(p->connections)+1 > MAX_CONNECTIONS) {
|
||||
pa_log(__FILE__": Warning! Too many connections (%u), dropping incoming connection.\n", MAX_CONNECTIONS);
|
||||
pa_iochannel_free(io);
|
||||
return;
|
||||
}
|
||||
|
||||
c = pa_xmalloc(sizeof(struct connection));
|
||||
c->io = io;
|
||||
c->sink_input = NULL;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue