limit the number of concurrent connections for all four protocols
[profile/ivi/pulseaudio-panda.git] / polyp / protocol-native.c
index 0102e0c..12ecfae 100644 (file)
@@ -4,7 +4,7 @@
   This file is part of polypaudio.
  
   polypaudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published
+  it under the terms of the GNU Lesser General Public License as published
   by the Free Software Foundation; either version 2 of the License,
   or (at your option) any later version.
  
@@ -13,7 +13,7 @@
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   General Public License for more details.
  
-  You should have received a copy of the GNU General Public License
+  You should have received a copy of the GNU Lesser General Public License
   along with polypaudio; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
   USA.
 #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);
@@ -1343,7 +1357,7 @@ static void command_get_server_info(struct pa_pdispatch *pd, uint32_t command, u
     pa_tagstruct_puts(reply, PACKAGE_NAME);
     pa_tagstruct_puts(reply, PACKAGE_VERSION);
     pa_tagstruct_puts(reply, pa_get_user_name(txt, sizeof(txt)));
-    pa_tagstruct_puts(reply, pa_get_host_name(txt, sizeof(txt)));
+    pa_tagstruct_puts(reply, pa_get_fqdn(txt, sizeof(txt)));
     pa_tagstruct_put_sample_spec(reply, &c->protocol->core->default_sample_spec);
 
     n = pa_namereg_get_default_sink_name(c->protocol->core);
@@ -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");