diff options
| author | Lennart Poettering <lennart@poettering.net> | 2004-11-18 00:28:26 +0000 | 
|---|---|---|
| committer | Lennart Poettering <lennart@poettering.net> | 2004-11-18 00:28:26 +0000 | 
| commit | eef235d8795df740eb63cb135bd187b7ab9ac4ea (patch) | |
| tree | 0667fdeb1ed052004a6375a175e35dd06ada3476 | |
| parent | c57d5deef6ee33ab892398c7fd27400cd4ce4542 (diff) | |
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
| -rw-r--r-- | polyp/protocol-cli.c | 10 | ||||
| -rw-r--r-- | polyp/protocol-esound.c | 56 | ||||
| -rw-r--r-- | polyp/protocol-native.c | 37 | ||||
| -rw-r--r-- | polyp/protocol-simple.c | 9 | 
4 files changed, 102 insertions, 10 deletions
diff --git a/polyp/protocol-cli.c b/polyp/protocol-cli.c index 7ce53887..7122d23a 100644 --- a/polyp/protocol-cli.c +++ b/polyp/protocol-cli.c @@ -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); diff --git a/polyp/protocol-esound.c b/polyp/protocol-esound.c index 07c39e2a..11a33315 100644 --- a/polyp/protocol-esound.c +++ b/polyp/protocol-esound.c @@ -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; + +    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)); diff --git a/polyp/protocol-native.c b/polyp/protocol-native.c index 02d81db3..12ecfae1 100644 --- a/polyp/protocol-native.c +++ b/polyp/protocol-native.c @@ -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"); diff --git a/polyp/protocol-simple.c b/polyp/protocol-simple.c index f7c69d6b..058d4b82 100644 --- a/polyp/protocol-simple.c +++ b/polyp/protocol-simple.c @@ -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;  | 
