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; }
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; }
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); }
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); }
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; }
static void break_client (struct ropa_client *c, Bool notify_clientp) { assert (c); client_ref (c); break_ccpairs (c, notify_clientp); client_deref (c); }
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; }
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; }
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; }
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; }
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)); }
/** * 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; }
/* 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; }
/** * 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; }
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); } }
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); }
network_client * network_client_ref(network_client *nc) { return (network_client*)client_ref((client_t*)nc); }