]> code.delx.au - pulseaudio/commitdiff
limit the number of concurrent connections for all four protocols
authorLennart Poettering <lennart@poettering.net>
Thu, 18 Nov 2004 00:28:26 +0000 (00:28 +0000)
committerLennart Poettering <lennart@poettering.net>
Thu, 18 Nov 2004 00:28:26 +0000 (00:28 +0000)
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

polyp/protocol-cli.c
polyp/protocol-esound.c
polyp/protocol-native.c
polyp/protocol-simple.c

index 7ce538878047c4f48b6ab464e07d343b6dd8beb3..7122d23a4e57a423580afe2a1f59bf4c5e4a4113 100644 (file)
 #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);
index 07c39e2a0a6443ea8fd2275a05510a3c665086a0..11a33315a7869428ba917d90b7fa0fc4280adf78 100644 (file)
 #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;
+
+    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 = c->protocol->core->mainloop->defer_new(c->protocol->core->mainloop, defer_callback, c);
+    c->defer_event = p->core->mainloop->defer_new(p->core->mainloop, defer_callback, c);
     assert(c->defer_event);
-    c->protocol->core->mainloop->defer_enable(c->defer_event, 0);
+    p->core->mainloop->defer_enable(c->defer_event, 0);
 
-    pa_idxset_put(c->protocol->connections, c, &c->index);
+    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));
index 02d81db3ed0856405e2a1f08c2b383a9b9f7ffd6..12ecfae149360f697c806099b1f2610e71b741ca 100644 (file)
 #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");
index f7c69d6b4cd5d23f2593f2df7333c6957895b1ac..058d4b828c6796e536b51049420f8e801e91eb24 100644 (file)
@@ -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;