Exemplo n.º 1
0
/*
 * Send auth failed message from server to client.
 */
void
send_auth_failed(struct context *c, const char *client_reason)
{
    struct gc_arena gc = gc_new();
    static const char auth_failed[] = "AUTH_FAILED";
    size_t len;

    schedule_exit(c, c->options.scheduled_exit_interval, SIGTERM);

    len = (client_reason ? strlen(client_reason)+1 : 0) + sizeof(auth_failed);
    if (len > PUSH_BUNDLE_SIZE)
    {
        len = PUSH_BUNDLE_SIZE;
    }

    {
        struct buffer buf = alloc_buf_gc(len, &gc);
        buf_printf(&buf, auth_failed);
        if (client_reason)
        {
            buf_printf(&buf, ",%s", client_reason);
        }
        send_control_channel_string(c, BSTR(&buf), D_PUSH);
    }

    gc_free(&gc);
}
Exemplo n.º 2
0
bool
send_push_reply (struct context *c)
{
  struct gc_arena gc = gc_new ();
  struct buffer buf = alloc_buf_gc (MAX_PUSH_LIST_LEN + 256, &gc);
  bool ret = false;

  buf_printf (&buf, "PUSH_REPLY");

  if (c->options.push_list && strlen (c->options.push_list->options))
    buf_printf (&buf, ",%s", c->options.push_list->options);

  if (c->c2.push_ifconfig_defined && c->c2.push_ifconfig_local && c->c2.push_ifconfig_remote_netmask)
    buf_printf (&buf, ",ifconfig %s %s",
		print_in_addr_t (c->c2.push_ifconfig_local, 0, &gc),
		print_in_addr_t (c->c2.push_ifconfig_remote_netmask, 0, &gc));

  if (strlen (BSTR (&buf)) < MAX_PUSH_LIST_LEN)
    ret = send_control_channel_string (c, BSTR (&buf), D_PUSH);
  else
    msg (M_WARN, "Maximum length of --push buffer (%d) has been exceeded", MAX_PUSH_LIST_LEN);

  gc_free (&gc);
  return ret;
}
Exemplo n.º 3
0
bool
send_push_request(struct context *c)
{
    const int max_push_requests = c->options.handshake_window / PUSH_REQUEST_INTERVAL;
    if (++c->c2.n_sent_push_requests <= max_push_requests)
    {
        return send_control_channel_string(c, "PUSH_REQUEST", D_PUSH);
    }
    else
    {
        msg(D_STREAM_ERRORS, "No reply from server after sending %d push requests", max_push_requests);
        c->sig->signal_received = SIGUSR1; /* SOFT-SIGUSR1 -- server-pushed connection reset */
        c->sig->signal_text = "no-push-reply";
        return false;
    }
}
Exemplo n.º 4
0
static bool
send_push_options(struct context *c, struct buffer *buf,
                  struct push_list *push_list, int safe_cap,
                  bool *push_sent, bool *multi_push)
{
    struct push_entry *e = push_list->head;

    while (e)
    {
        if (e->enable)
        {
            const int l = strlen(e->option);
            if (BLEN(buf) + l >= safe_cap)
            {
                buf_printf(buf, ",push-continuation 2");
                {
                    const bool status = send_control_channel_string(c, BSTR(buf), D_PUSH);
                    if (!status)
                    {
                        return false;
                    }
                    *push_sent = true;
                    *multi_push = true;
                    buf_reset_len(buf);
                    buf_printf(buf, "%s", push_reply_cmd);
                }
            }
            if (BLEN(buf) + l >= safe_cap)
            {
                msg(M_WARN, "--push option is too long");
                return false;
            }
            buf_printf(buf, ",%s", e->option);
        }
        e = e->next;
    }
    return true;
}
Exemplo n.º 5
0
static bool
send_push_reply(struct context *c, struct push_list *per_client_push_list)
{
    struct gc_arena gc = gc_new();
    struct buffer buf = alloc_buf_gc(PUSH_BUNDLE_SIZE, &gc);
    bool multi_push = false;
    const int extra = 84; /* extra space for possible trailing ifconfig and push-continuation */
    const int safe_cap = BCAP(&buf) - extra;
    bool push_sent = false;

    buf_printf(&buf, "%s", push_reply_cmd);

    /* send options which are common to all clients */
    if (!send_push_options(c, &buf, &c->options.push_list, safe_cap,
                           &push_sent, &multi_push))
    {
        goto fail;
    }

    /* send client-specific options */
    if (!send_push_options(c, &buf, per_client_push_list, safe_cap,
                           &push_sent, &multi_push))
    {
        goto fail;
    }

    if (multi_push)
    {
        buf_printf(&buf, ",push-continuation 1");
    }

    if (BLEN(&buf) > sizeof(push_reply_cmd)-1)
    {
        const bool status = send_control_channel_string(c, BSTR(&buf), D_PUSH);
        if (!status)
        {
            goto fail;
        }
        push_sent = true;
    }

    /* If nothing have been pushed, send an empty push,
     * as the client is expecting a response
     */
    if (!push_sent)
    {
        bool status = false;

        buf_reset_len(&buf);
        buf_printf(&buf, "%s", push_reply_cmd);
        status = send_control_channel_string(c, BSTR(&buf), D_PUSH);
        if (!status)
        {
            goto fail;
        }
    }

    gc_free(&gc);
    return true;

fail:
    gc_free(&gc);
    return false;
}
Exemplo n.º 6
0
/*
 * Send restart message from server to client.
 */
void
send_restart(struct context *c, const char *kill_msg)
{
    schedule_exit(c, c->options.scheduled_exit_interval, SIGTERM);
    send_control_channel_string(c, kill_msg ? kill_msg : "RESTART", D_PUSH);
}
Exemplo n.º 7
0
bool
send_push_reply (struct context *c)
{
  struct gc_arena gc = gc_new ();
  struct buffer buf = alloc_buf_gc (PUSH_BUNDLE_SIZE, &gc);
  struct push_entry *e = c->options.push_list.head;
  bool multi_push = false;
  static char cmd[] = "PUSH_REPLY";
  const int extra = 84; /* extra space for possible trailing ifconfig and push-continuation */
  const int safe_cap = BCAP (&buf) - extra;
  bool push_sent = false;

  msg( M_INFO, "send_push_reply(): safe_cap=%d", safe_cap );

  buf_printf (&buf, "%s", cmd);

  if ( c->c2.push_ifconfig_ipv6_defined )
    {
      /* IPv6 is put into buffer first, could be lengthy */
      buf_printf( &buf, ",ifconfig-ipv6 %s/%d %s",
		    print_in6_addr( c->c2.push_ifconfig_ipv6_local, 0, &gc),
		    c->c2.push_ifconfig_ipv6_netbits,
		    print_in6_addr( c->c2.push_ifconfig_ipv6_remote, 0, &gc) );
      if (BLEN (&buf) >= safe_cap)
	{
	  msg (M_WARN, "--push ifconfig-ipv6 option is too long");
	  goto fail;
	}
    }

  while (e)
    {
      if (e->enable)
	{
	  const int l = strlen (e->option);
	  if (BLEN (&buf) + l >= safe_cap)
	    {
	      buf_printf (&buf, ",push-continuation 2");
	      {
		const bool status = send_control_channel_string (c, BSTR (&buf), D_PUSH);
		if (!status)
		  goto fail;
		push_sent = true;
		multi_push = true;
		buf_reset_len (&buf);
		buf_printf (&buf, "%s", cmd);
	      }
	    }
	  if (BLEN (&buf) + l >= safe_cap)
	    {
	      msg (M_WARN, "--push option is too long");
	      goto fail;
	    }
	  buf_printf (&buf, ",%s", e->option);
	}
      e = e->next;
    }

  if (c->c2.push_ifconfig_defined && c->c2.push_ifconfig_local && c->c2.push_ifconfig_remote_netmask)
    {
      in_addr_t ifconfig_local = c->c2.push_ifconfig_local;
#ifdef ENABLE_CLIENT_NAT
      if (c->c2.push_ifconfig_local_alias)
	ifconfig_local = c->c2.push_ifconfig_local_alias;
#endif
      buf_printf (&buf, ",ifconfig %s %s",
		  print_in_addr_t (ifconfig_local, 0, &gc),
		  print_in_addr_t (c->c2.push_ifconfig_remote_netmask, 0, &gc));
    }
  if (multi_push)
    buf_printf (&buf, ",push-continuation 1");

  if (BLEN (&buf) > sizeof(cmd)-1)
    {
      const bool status = send_control_channel_string (c, BSTR (&buf), D_PUSH);
      if (!status)
        goto fail;
      push_sent = true;
    }

  /* If nothing have been pushed, send an empty push,
   * as the client is expecting a response
   */
  if (!push_sent)
    {
      bool status = false;

      buf_reset_len (&buf);
      buf_printf (&buf, "%s", cmd);
      status = send_control_channel_string (c, BSTR(&buf), D_PUSH);
      if (!status)
	goto fail;
    }

  gc_free (&gc);
  return true;

 fail:
  gc_free (&gc);
  return false;
}
Exemplo n.º 8
0
bool
send_push_request (struct context *c)
{
  return send_control_channel_string (c, "PUSH_REQUEST", D_PUSH);
}
Exemplo n.º 9
0
/*
 * Send auth failed message from server to client.
 */
void
send_auth_failed (struct context *c)
{
  schedule_exit (c, c->options.scheduled_exit_interval);
  send_control_channel_string (c, "AUTH_FAILED", D_PUSH);
}