예제 #1
0
파일: rtp_sinker.c 프로젝트: dulton/nampu
static int32_t
rtp_sinker_set_config(network_sinker *sinker, void *in, void *data)
{
    rtp_sinker *rs = (rtp_sinker*)sinker;
    int32_t stm_i = *((int32_t*)in);
    rtp_port_conf *rpc = (rtp_port_conf*)data;
    proto_watch *pw;

    if (!VALID_STM_TYPE(stm_i) || sinker->stms[stm_i].stm_type == ST_NONE)
        return -EINVAL;

    if (!rpc->rtsp_client)
        return -EINVAL;

    rs->trans_mode = rpc->trans;
    pw = sinker->stms[stm_i].stm_watch;
    if (!pw)
    {
        if (rpc->trans != RTP_OVER_RTSP)
            return -EINVAL;

        if (!rs->interleaved)
        {
            rs->interleaved = (rtsp_client*)client_ref((client*)rpc->rtsp_client);
        }

        return 0;
    }

    if (!proto_watch_attach(pw, ((client*)rpc->rtsp_client)->sched))
        return proto_watch_set_dst(pw, rpc->host, rpc->ports.min_port);

    return -EINVAL;
}
예제 #2
0
int client_auth_begin(struct client *client, const char *mech_name,
		      const char *init_resp)
{
	if (!client->secured && strcmp(client->ssl_set->ssl, "required") == 0) {
		if (client->set->auth_verbose) {
			client_log(client, "Login failed: "
				   "SSL required for authentication");
		}
		client->auth_attempts++;
		client_auth_result(client, CLIENT_AUTH_RESULT_SSL_REQUIRED, NULL,
			"Authentication not allowed until SSL/TLS is enabled.");
		return 1;
	}


	client_ref(client);
	client->auth_initializing = TRUE;
	sasl_server_auth_begin(client, login_binary->protocol, mech_name,
			       init_resp, sasl_callback);
	client->auth_initializing = FALSE;
	if (!client->authenticating)
		return 1;

	/* don't handle input until we get the initial auth reply */
	if (client->io != NULL)
		io_remove(&client->io);
	client_set_auth_waiting(client);
	return 0;
}
예제 #3
0
static void
has_connection (Client *client)
{
  /* listen for disconnection */
  client->disconnected_signal_handler_id = g_signal_connect (client->connection,
                                                             "closed",
                                                             G_CALLBACK (on_connection_disconnected),
                                                             client);

  /* attempt to acquire the name */
  g_dbus_connection_call (client->connection,
                          "org.freedesktop.DBus",  /* bus name */
                          "/org/freedesktop/DBus", /* object path */
                          "org.freedesktop.DBus",  /* interface name */
                          "RequestName",           /* method name */
                          g_variant_new ("(su)",
                                         client->name,
                                         client->flags),
                          G_VARIANT_TYPE ("(u)"),
                          G_DBUS_CALL_FLAGS_NONE,
                          -1,
                          NULL,
                          (GAsyncReadyCallback) request_name_cb,
                          client_ref (client));
}
static void client_start_tls(struct client *client)
{
	int fd_ssl;

	client_ref(client);
	if (!client_unref(&client) || client->destroyed)
		return;

	fd_ssl = ssl_proxy_alloc(client->fd, &client->ip, client->pool,
				 client->set, client->ssl_set,
				 &client->ssl_proxy);
	if (fd_ssl == -1) {
		client_notify_disconnect(client,
			CLIENT_DISCONNECT_INTERNAL_ERROR,
			"TLS initialization failed.");
		client_destroy(client,
			"Disconnected: TLS initialization failed.");
		return;
	}
	ssl_proxy_set_client(client->ssl_proxy, client);
	ssl_proxy_start(client->ssl_proxy);

	client->starttls = TRUE;
	client->tls = TRUE;
	client->secured = TRUE;
	login_refresh_proctitle();

	client->fd = fd_ssl;
	client->io = io_add(client->fd, IO_READ, client_input, client);
	i_stream_unref(&client->input);
	o_stream_unref(&client->output);
	client_open_streams(client);

	client->v.starttls(client);
}
예제 #5
0
static void
break_callback (struct ropa_cb *cb, struct ropa_client *caller, Bool break_own)
{
    struct ropa_ccpair *cc;
    struct ropa_ccpair *own_cc = NULL;

    assert (cb);
    assert (cb->ccpairs);

    mlog_log (MDEBROPA, "break_callback: breaking callback %x.%x.%x (%d)",
	    cb->fid.Volume, cb->fid.Vnode, cb->fid.Unique, break_own);

    callback_ref (cb);
    if (caller)
	client_ref (caller);

    while ((cc = listdelhead (cb->ccpairs)) != 0) {
	assert (cc->cb == cb);
	cc->cb_li = NULL;
	if (break_own)
	    break_ccpair (cc, cc->client != caller);
	else
	    if (cc->client == caller)
		own_cc = cc;
	    else
		break_ccpair (cc, TRUE);
    }

    if (own_cc)
	own_cc->cb_li = listaddhead (cb->ccpairs, own_cc);

    callback_deref (cb);
    if (caller)
	client_deref (caller);
}
예제 #6
0
파일: rtp_sinker.c 프로젝트: dulton/nampu
static int32_t
rtp_sinker_consumable(network_sinker *ns, proto_watch *pw,
                      int32_t stm_i, uint32_t size)
{
    int32_t err = -EINVAL;
    media_sinker *sinker = (media_sinker*)ns;
    rtp_sinker *rs = (rtp_sinker*)ns;
    network_client *nc = (network_client*)rs->interleaved;

    if (rs->trans_mode == RTP_OVER_RTSP && nc)
    {   //@{Interleaved rtp mode}
        client_ref((client*)nc);
        RELEASE_LOCK(sinker->lock);

        err = network_client_consumable(nc, size);
        client_unref((client*)nc);

        AQUIRE_LOCK(sinker->lock);
        return err;
    }

    if (pw)
    {
        return proto_watch_writeable(pw, size);
    }

    return err;
}
예제 #7
0
static void
break_client (struct ropa_client *c, Bool notify_clientp)
{
    assert (c);
    
    client_ref (c);
    break_ccpairs (c, notify_clientp);
    client_deref (c);
}
예제 #8
0
파일: login-proxy.c 프로젝트: bjacke/core
int login_proxy_new(struct client *client,
		    const struct login_proxy_settings *set,
		    proxy_callback_t *callback)
{
	struct login_proxy *proxy;

	i_assert(client->login_proxy == NULL);

	if (set->host == NULL || *set->host == '\0') {
		i_error("proxy(%s): host not given", client->virtual_user);
		return -1;
	}

	if (client->proxy_ttl <= 1) {
		i_error("proxy(%s): TTL reached zero - "
			"proxies appear to be looping?", client->virtual_user);
		return -1;
	}

	proxy = i_new(struct login_proxy, 1);
	proxy->client = client;
	proxy->client_fd = -1;
	proxy->server_fd = -1;
	proxy->created = ioloop_timeval;
	proxy->ip = set->ip;
	proxy->source_ip = set->source_ip;
	proxy->host = i_strdup(set->host);
	proxy->port = set->port;
	proxy->connect_timeout_msecs = set->connect_timeout_msecs;
	proxy->notify_refresh_secs = set->notify_refresh_secs;
	proxy->ssl_flags = set->ssl_flags;
	proxy->state_rec = login_proxy_state_get(proxy_state, &proxy->ip,
						 proxy->port);
	client_ref(client);

	if (set->ip.family == 0 &&
	    net_addr2ip(set->host, &proxy->ip) < 0) {
		i_error("proxy(%s): BUG: host %s is not an IP "
			"(auth should have changed it)",
			client->virtual_user, set->host);
	} else {
		if (login_proxy_connect(proxy) < 0)
			return -1;
	}

	DLLIST_PREPEND(&login_proxies_pending, proxy);

	proxy->callback = callback;
	client->login_proxy = proxy;
	return 0;
}
예제 #9
0
파일: client_set.c 프로젝트: dulton/nampu
int32_t client_set_add(client_set *cs, client *c)
{
	int32_t err;

	AQUIRE_LOCK(cs->lock);
	err = __client_set_add(cs, c);
	if (!err)
	{
		client_ref(c);
	}
	RELEASE_LOCK(cs->lock);

	return err;
}
예제 #10
0
static struct ropa_ccpair *
add_client (struct ropa_cb *cb, struct ropa_client *c)
{
    struct timeval tv;
    struct ropa_ccpair cckey, *cc;

    assert (cb && c);

    cckey.client = c;
    cckey.cb = cb;
    
    cc = hashtabsearch (ht_ccpairs, &cckey);

    if (cc) {
	listdel (lru_ccpair, cc->li);
	cc->li = listaddhead (lru_ccpair, cc);
	return cc;
    }

    /* The reverse of these are in break_ccpair */
    callback_ref (cb);
    client_ref (c);

    cc = listdeltail (lru_ccpair);
    DIAGNOSTIC_CHECK_CCPAIR(cc);    
    cc->li = NULL;

    if (ccpairs_inuse_p (cc))
	break_ccpair (cc, TRUE);

    /* XXX  do it for real */
    gettimeofday(&tv, NULL);
    cc->expire = tv.tv_sec + 3600;
    
    heap_insert (heap_ccpairs, cc, &cc->heap);
    LWP_NoYieldSignal (heap_ccpairs);
    cc->cb_li = listaddtail (cb->ccpairs, cc);
    
    cc->client = c;
    cc->cb = cb;
    cc->li = listaddhead (lru_ccpair, cc);
    hashtabadd (ht_ccpairs, cc);

    mlog_log (MDEBROPA, "add_client: added %x to callback %x.%x.%x",
	    c->addr[0].addr_in, cb->fid.Volume, cb->fid.Vnode, cb->fid.Unique);

    return cc;
}
예제 #11
0
int login_proxy_new(struct client *client,
		    const struct login_proxy_settings *set,
		    proxy_callback_t *callback)
{
	struct login_proxy *proxy;

	i_assert(client->login_proxy == NULL);

	if (set->host == NULL || *set->host == '\0') {
		client_log_err(client, t_strdup_printf(
			"proxy(%s): host not given", client->virtual_user));
		return -1;
	}

	if (client->proxy_ttl <= 1) {
		client_log_err(client, t_strdup_printf(
			"proxy(%s): TTL reached zero - "
			"proxies appear to be looping?", client->virtual_user));
		return -1;
	}

	proxy = i_new(struct login_proxy, 1);
	proxy->client = client;
	proxy->client_fd = -1;
	proxy->server_fd = -1;
	proxy->created = ioloop_timeval;
	proxy->ip = set->ip;
	proxy->source_ip = set->source_ip;
	proxy->host = i_strdup(set->host);
	proxy->port = set->port;
	proxy->connect_timeout_msecs = set->connect_timeout_msecs;
	proxy->notify_refresh_secs = set->notify_refresh_secs;
	proxy->ssl_flags = set->ssl_flags;
	proxy->state_rec = login_proxy_state_get(proxy_state, &proxy->ip,
						 proxy->port);
	client_ref(client);

	if (login_proxy_connect(proxy) < 0) {
		login_proxy_free(&proxy);
		return -1;
	}

	DLLIST_PREPEND(&login_proxies_pending, proxy);

	proxy->callback = callback;
	client->login_proxy = proxy;
	return 0;
}
예제 #12
0
static void
invoke_get_name_owner (Client *client)
{
  g_dbus_connection_call (client->connection,
                          "org.freedesktop.DBus",  /* bus name */
                          "/org/freedesktop/DBus", /* object path */
                          "org.freedesktop.DBus",  /* interface name */
                          "GetNameOwner",          /* method name */
                          g_variant_new ("(s)", client->name),
                          G_VARIANT_TYPE ("(s)"),
                          G_DBUS_CALL_FLAGS_NONE,
                          -1,
                          NULL,
                          (GAsyncReadyCallback) get_name_owner_cb,
                          client_ref (client));
}
예제 #13
0
/**
 * g_bus_own_name:
 * @bus_type: The type of bus to own a name on.
 * @name: The well-known name to own.
 * @flags: A set of flags from the #GBusNameOwnerFlags enumeration.
 * @bus_acquired_handler: Handler to invoke when connected to the bus of type @bus_type or %NULL.
 * @name_acquired_handler: Handler to invoke when @name is acquired or %NULL.
 * @name_lost_handler: Handler to invoke when @name is lost or %NULL.
 * @user_data: User data to pass to handlers.
 * @user_data_free_func: Function for freeing @user_data or %NULL.
 *
 * Starts acquiring @name on the bus specified by @bus_type and calls
 * @name_acquired_handler and @name_lost_handler when the name is
 * acquired respectively lost. Callbacks will be invoked in the <link
 * linkend="g-main-context-push-thread-default">thread-default main
 * loop</link> of the thread you are calling this function from.
 *
 * You are guaranteed that one of the @name_acquired_handler and @name_lost_handler
 * callbacks will be invoked after calling this function - there are three
 * possible cases:
 * <itemizedlist>
 *   <listitem><para>
 *     @name_lost_handler with a %NULL connection (if a connection to the bus can't be made).
 *   </para></listitem>
 *   <listitem><para>
 *     @bus_acquired_handler then @name_lost_handler (if the name can't be obtained)
 *   </para></listitem>
 *   <listitem><para>
 *     @bus_acquired_handler then @name_acquired_handler (if the name was obtained).
 *   </para></listitem>
 * </itemizedlist>
 * When you are done owning the name, just call g_bus_unown_name()
 * with the owner id this function returns.
 *
 * If the name is acquired or lost (for example another application
 * could acquire the name if you allow replacement or the application
 * currently owning the name exits), the handlers are also invoked. If the
 * #GDBusConnection that is used for attempting to own the name
 * closes, then @name_lost_handler is invoked since it is no
 * longer possible for other processes to access the process.
 *
 * You cannot use g_bus_own_name() several times for the same name (unless
 * interleaved with calls to g_bus_unown_name()) - only the first call
 * will work.
 *
 * Another guarantee is that invocations of @name_acquired_handler
 * and @name_lost_handler are guaranteed to alternate; that
 * is, if @name_acquired_handler is invoked then you are
 * guaranteed that the next time one of the handlers is invoked, it
 * will be @name_lost_handler. The reverse is also true.
 *
 * If you plan on exporting objects (using e.g.
 * g_dbus_connection_register_object()), note that it is generally too late
 * to export the objects in @name_acquired_handler. Instead, you can do this
 * in @bus_acquired_handler since you are guaranteed that this will run
 * before @name is requested from the bus.
 *
 * This behavior makes it very simple to write applications that wants
 * to own names and export objects, see <xref linkend="gdbus-owning-names"/>.
 * Simply register objects to be exported in @bus_acquired_handler and
 * unregister the objects (if any) in @name_lost_handler.
 *
 * Returns: An identifier (never 0) that an be used with
 * g_bus_unown_name() to stop owning the name.
 *
 * Since: 2.26
 */
guint
g_bus_own_name (GBusType                  bus_type,
                const gchar              *name,
                GBusNameOwnerFlags        flags,
                GBusAcquiredCallback      bus_acquired_handler,
                GBusNameAcquiredCallback  name_acquired_handler,
                GBusNameLostCallback      name_lost_handler,
                gpointer                  user_data,
                GDestroyNotify            user_data_free_func)
{
  Client *client;

  g_return_val_if_fail (g_dbus_is_name (name) && !g_dbus_is_unique_name (name), 0);

  G_LOCK (lock);

  client = g_new0 (Client, 1);
  client->ref_count = 1;
  client->id = next_global_id++; /* TODO: uh oh, handle overflow */
  client->name = g_strdup (name);
  client->flags = flags;
  client->bus_acquired_handler = bus_acquired_handler;
  client->name_acquired_handler = name_acquired_handler;
  client->name_lost_handler = name_lost_handler;
  client->user_data = user_data;
  client->user_data_free_func = user_data_free_func;
  client->main_context = g_main_context_get_thread_default ();
  if (client->main_context != NULL)
    g_main_context_ref (client->main_context);

  if (map_id_to_client == NULL)
    {
      map_id_to_client = g_hash_table_new (g_direct_hash, g_direct_equal);
    }
  g_hash_table_insert (map_id_to_client,
                       GUINT_TO_POINTER (client->id),
                       client);

  g_bus_get (bus_type,
             NULL,
             connection_get_cb,
             client_ref (client));

  G_UNLOCK (lock);

  return client->id;
}
예제 #14
0
/* Return a reference to the #Client for @watcher_id, or %NULL if it’s been
 * unwatched. This is safe to call from any thread. */
static Client *
dup_client (guint watcher_id)
{
  Client *client;

  G_LOCK (lock);

  g_assert (watcher_id != 0);
  g_assert (map_id_to_client != NULL);

  client = g_hash_table_lookup (map_id_to_client, GUINT_TO_POINTER (watcher_id));

  if (client != NULL)
    client_ref (client);

  G_UNLOCK (lock);

  return client;
}
예제 #15
0
/**
 * g_bus_watch_name:
 * @bus_type: The type of bus to watch a name on.
 * @name: The name (well-known or unique) to watch.
 * @flags: Flags from the #GBusNameWatcherFlags enumeration.
 * @name_appeared_handler: (nullable): Handler to invoke when @name is known to exist or %NULL.
 * @name_vanished_handler: (nullable): Handler to invoke when @name is known to not exist or %NULL.
 * @user_data: User data to pass to handlers.
 * @user_data_free_func: (nullable): Function for freeing @user_data or %NULL.
 *
 * Starts watching @name on the bus specified by @bus_type and calls
 * @name_appeared_handler and @name_vanished_handler when the name is
 * known to have a owner respectively known to lose its
 * owner. Callbacks will be invoked in the
 * [thread-default main context][g-main-context-push-thread-default]
 * of the thread you are calling this function from.
 *
 * You are guaranteed that one of the handlers will be invoked after
 * calling this function. When you are done watching the name, just
 * call g_bus_unwatch_name() with the watcher id this function
 * returns.
 *
 * If the name vanishes or appears (for example the application owning
 * the name could restart), the handlers are also invoked. If the
 * #GDBusConnection that is used for watching the name disconnects, then
 * @name_vanished_handler is invoked since it is no longer
 * possible to access the name.
 *
 * Another guarantee is that invocations of @name_appeared_handler
 * and @name_vanished_handler are guaranteed to alternate; that
 * is, if @name_appeared_handler is invoked then you are
 * guaranteed that the next time one of the handlers is invoked, it
 * will be @name_vanished_handler. The reverse is also true.
 *
 * This behavior makes it very simple to write applications that want
 * to take action when a certain [name exists][gdbus-watching-names].
 * Basically, the application should create object proxies in
 * @name_appeared_handler and destroy them again (if any) in
 * @name_vanished_handler.
 *
 * Returns: An identifier (never 0) that an be used with
 * g_bus_unwatch_name() to stop watching the name.
 *
 * Since: 2.26
 */
guint
g_bus_watch_name (GBusType                  bus_type,
                  const gchar              *name,
                  GBusNameWatcherFlags      flags,
                  GBusNameAppearedCallback  name_appeared_handler,
                  GBusNameVanishedCallback  name_vanished_handler,
                  gpointer                  user_data,
                  GDestroyNotify            user_data_free_func)
{
  Client *client;

  g_return_val_if_fail (g_dbus_is_name (name), 0);

  G_LOCK (lock);

  client = g_new0 (Client, 1);
  client->ref_count = 1;
  client->id = g_atomic_int_add (&next_global_id, 1); /* TODO: uh oh, handle overflow */
  client->name = g_strdup (name);
  client->flags = flags;
  client->name_appeared_handler = name_appeared_handler;
  client->name_vanished_handler = name_vanished_handler;
  client->user_data = user_data;
  client->user_data_free_func = user_data_free_func;
  client->main_context = g_main_context_ref_thread_default ();

  if (map_id_to_client == NULL)
    {
      map_id_to_client = g_hash_table_new (g_direct_hash, g_direct_equal);
    }
  g_hash_table_insert (map_id_to_client,
                       GUINT_TO_POINTER (client->id),
                       client);

  g_bus_get (bus_type,
             NULL,
             connection_get_cb,
             client_ref (client));

  G_UNLOCK (lock);

  return client->id;
}
예제 #16
0
static void
has_connection (Client *client)
{
  /* listen for disconnection */
  client->disconnected_signal_handler_id = g_signal_connect (client->connection,
                                                             "closed",
                                                             G_CALLBACK (on_connection_disconnected),
                                                             GUINT_TO_POINTER (client->id));

  /* start listening to NameOwnerChanged messages immediately */
  client->name_owner_changed_subscription_id = g_dbus_connection_signal_subscribe (client->connection,
                                                                                   "org.freedesktop.DBus",  /* name */
                                                                                   "org.freedesktop.DBus",  /* if */
                                                                                   "NameOwnerChanged",      /* signal */
                                                                                   "/org/freedesktop/DBus", /* path */
                                                                                   client->name,
                                                                                   G_DBUS_SIGNAL_FLAGS_NONE,
                                                                                   on_name_owner_changed,
                                                                                   GUINT_TO_POINTER (client->id),
                                                                                   NULL);

  if (client->flags & G_BUS_NAME_WATCHER_FLAGS_AUTO_START)
    {
      g_dbus_connection_call (client->connection,
                              "org.freedesktop.DBus",  /* bus name */
                              "/org/freedesktop/DBus", /* object path */
                              "org.freedesktop.DBus",  /* interface name */
                              "StartServiceByName",    /* method name */
                              g_variant_new ("(su)", client->name, 0),
                              G_VARIANT_TYPE ("(u)"),
                              G_DBUS_CALL_FLAGS_NONE,
                              -1,
                              NULL,
                              (GAsyncReadyCallback) start_service_by_name_cb,
                              client_ref (client));
    }
  else
    {
      /* check owner */
      invoke_get_name_owner (client);
    }
}
예제 #17
0
static void
schedule_call_in_idle (Client *client, CallType  call_type)
{
  CallHandlerData *data;
  GSource *idle_source;

  data = g_new0 (CallHandlerData, 1);
  data->client = client_ref (client);
  data->connection = client->connection != NULL ? g_object_ref (client->connection) : NULL;
  data->call_type = call_type;

  idle_source = g_idle_source_new ();
  g_source_set_priority (idle_source, G_PRIORITY_HIGH);
  g_source_set_callback (idle_source,
                         call_in_idle_cb,
                         data,
                         (GDestroyNotify) call_handler_data_free);
  g_source_attach (idle_source, client->main_context);
  g_source_unref (idle_source);
}
예제 #18
0
파일: network_client.c 프로젝트: waycom/h6
network_client *
network_client_ref(network_client *nc)
{
	return (network_client*)client_ref((client_t*)nc);
}