}
}
-const struct buffer *
+struct buffer *
buffer_list_peek (struct buffer_list *ol)
{
if (ol->head)
return NULL;
}
+void
+buffer_list_aggregate (struct buffer_list *bl, const size_t max)
+{
+ if (bl->head)
+ {
+ struct buffer_entry *more = bl->head;
+ size_t size = 0;
+ int count = 0;
+ for (count = 0; more && size <= max; ++count)
+ {
+ size += BLEN(&more->buf);
+ more = more->next;
+ }
+
+ if (count >= 2)
+ {
+ int i;
+ struct buffer_entry *e = bl->head, *f;
+
+ ALLOC_OBJ_CLEAR (f, struct buffer_entry);
+ f->buf.data = malloc (size);
+ check_malloc_return (f->buf.data);
+ f->buf.capacity = size;
+ for (i = 0; e && i < count; ++i)
+ {
+ struct buffer_entry *next = e->next;
+ buf_copy (&f->buf, &e->buf);
+ free_buf (&e->buf);
+ free (e);
+ e = next;
+ }
+ bl->head = f;
+ f->next = more;
+ if (!more)
+ bl->tail = f;
+ }
+ }
+}
+
static void
buffer_list_pop (struct buffer_list *ol)
{
}
#endif
+#ifdef BUFFER_LIST_AGGREGATE_TEST
+ /* test buffer_list_aggregate function */
+ {
+ static const char *text[] = {
+ "It was a bright cold day in April, ",
+ "and the clocks were striking ",
+ "thirteen. ",
+ "Winston Smith, ",
+ "his chin nuzzled into his breast in an ",
+ "effort to escape the vile wind, ",
+ "slipped quickly through the glass doors ",
+ "of Victory Mansions, though not quickly ",
+ "enough to prevent a swirl of gritty dust from ",
+ "entering along with him."
+ };
+
+ int iter, listcap;
+ for (listcap = 0; listcap < 12; ++listcap)
+ {
+ for (iter = 0; iter < 512; ++iter)
+ {
+ struct buffer_list *bl = buffer_list_new(listcap);
+ {
+ int i;
+ for (i = 0; i < SIZE(text); ++i)
+ buffer_list_push(bl, (unsigned char *)text[i]);
+ }
+ printf("[cap=%d i=%d] *************************\n", listcap, iter);
+ if (!(iter & 8))
+ buffer_list_aggregate(bl, iter/2);
+ if (!(iter & 16))
+ buffer_list_push(bl, (unsigned char *)"Even more text...");
+ buffer_list_aggregate(bl, iter);
+ if (!(iter & 1))
+ buffer_list_push(bl, (unsigned char *)"More text...");
+ {
+ struct buffer *buf;
+ while ((buf = buffer_list_peek(bl)))
+ {
+ int c;
+ printf ("'");
+ while ((c = buf_read_u8(buf)) >= 0)
+ putchar(c);
+ printf ("'\n");
+ buffer_list_advance(bl, 0);
+ }
+ }
+ buffer_list_free(bl);
+ }
+ }
+ return false;
+ }
+#endif
+
return true;
}
msg (M_CLIENT, "client-deny CID KID R [CR] : Deny auth client-id/key-id CID/KID with log reason");
msg (M_CLIENT, " text R and optional client reason text CR");
msg (M_CLIENT, "client-kill CID : Kill client instance CID");
+ msg (M_CLIENT, "env-filter [level] : Set env-var filter level");
#ifdef MANAGEMENT_PF
msg (M_CLIENT, "client-pf CID : Define packet filter for client CID (MULTILINE)");
#endif
}
}
+static void
+man_env_filter (struct management *man, const int level)
+{
+ man->connection.env_filter_level = level;
+ msg (M_CLIENT, "SUCCESS: env_filter_level=%d", level);
+}
+
#ifdef MANAGEMENT_PF
static void
{
man_client_n_clients (man);
}
+ else if (streq (p[0], "env-filter"))
+ {
+ int level = 0;
+ if (p[1])
+ level = atoi (p[1]);
+ man_env_filter (man, level);
+ }
#endif
else if (streq (p[0], "signal"))
{
static int
man_write (struct management *man)
{
- const int max_send = 256;
+ const int size_hint = 1024;
int sent = 0;
+ const struct buffer *buf;
- const struct buffer *buf = buffer_list_peek (man->connection.out);
+ buffer_list_aggregate(man->connection.out, size_hint);
+ buf = buffer_list_peek (man->connection.out);
if (buf && BLEN (buf))
{
- const int len = min_int (max_send, BLEN (buf));
+ const int len = min_int (size_hint, BLEN (buf));
sent = send (man->connection.sd_cli, BPTR (buf), len, MSG_NOSIGNAL);
if (sent >= 0)
{
#ifdef MANAGEMENT_DEF_AUTH
+static bool
+env_filter_match (const char *env_str, const int env_filter_level)
+{
+ static const char *env_names[] = {
+ "username=",
+ "password=",
+ "X509_0_CN=",
+ "tls_serial_0=",
+ "untrusted_ip=",
+ "ifconfig_local=",
+ "ifconfig_netmask=",
+ "daemon_start_time=",
+ "daemon_pid=",
+ "dev=",
+ "ifconfig_pool_remote_ip=",
+ "ifconfig_pool_netmask=",
+ "time_duration=",
+ "bytes_sent=",
+ "bytes_received="
+ };
+ if (env_filter_level >= 1)
+ {
+ size_t i;
+ for (i = 0; i < SIZE(env_names); ++i)
+ {
+ const char *en = env_names[i];
+ const size_t len = strlen(en);
+ if (strncmp(env_str, en, len) == 0)
+ return true;
+ }
+ return false;
+ }
+ else
+ return true;
+}
+
static void
-man_output_env (const struct env_set *es, const bool tail)
+man_output_env (const struct env_set *es, const bool tail, const int env_filter_level)
{
if (es)
{
struct env_item *e;
for (e = es->list; e != NULL; e = e->next)
{
- if (e->string)
+ if (e->string && (!env_filter_level || env_filter_match(e->string, env_filter_level)))
msg (M_CLIENT, ">CLIENT:ENV,%s", e->string);
}
}
const int nclients = (*man->persist.callback.n_clients) (man->persist.callback.arg);
setenv_int (es, "n_clients", nclients);
}
- man_output_env (es, false);
+ man_output_env (es, false, man->connection.env_filter_level);
gc_free (&gc);
}
mode = "REAUTH";
msg (M_CLIENT, ">CLIENT:%s,%lu,%u", mode, mdac->cid, mda_key_id);
man_output_extra_env (management);
- man_output_env (es, true);
+ man_output_env (es, true, management->connection.env_filter_level);
mdac->flags |= DAF_INITIAL_AUTH;
}
}
mdac->flags |= DAF_CONNECTION_ESTABLISHED;
msg (M_CLIENT, ">CLIENT:ESTABLISHED,%lu", mdac->cid);
man_output_extra_env (management);
- man_output_env (es, true);
+ man_output_env (es, true, management->connection.env_filter_level);
}
void
if ((mdac->flags & DAF_INITIAL_AUTH) && !(mdac->flags & DAF_CONNECTION_CLOSED))
{
msg (M_CLIENT, ">CLIENT:DISCONNECT,%lu", mdac->cid);
- man_output_env (es, true);
+ man_output_env (es, true, management->connection.env_filter_level);
mdac->flags |= DAF_CONNECTION_CLOSED;
}
}