static void do_test1(GObject *sender, GAsyncResult *res, gpointer data) { GList *services = NULL; GError *error = NULL; GResolver *resolver; const char *servername = data; int port = 3478; services = g_resolver_lookup_service_finish(G_RESOLVER(sender), res, &error); if(error != NULL) { purple_debug_info("stun", "Failed to look up srv record : %s\n", error->message); g_error_free(error); } else { servername = g_srv_target_get_hostname((GSrvTarget *)services->data); port = g_srv_target_get_port((GSrvTarget *)services->data); } purple_debug_info("stun", "connecting to %s:%d\n", servername, port); resolver = g_resolver_get_default(); g_resolver_lookup_by_name_async(resolver, servername, NULL, hbn_cb, GINT_TO_POINTER(port)); g_object_unref(resolver); g_resolver_free_targets(services); }
static void address_enumerate_cb (GObject *object, GAsyncResult *result, gpointer user_data) { GTask *task = user_data; GProxyAddressEnumeratorPrivate *priv = g_task_get_task_data (task); g_clear_error (&priv->last_error); priv->proxy_address = g_socket_address_enumerator_next_finish (priv->addr_enum, result, &priv->last_error); if (priv->proxy_address) { if (!priv->supports_hostname && !priv->dest_ips) { GResolver *resolver; resolver = g_resolver_get_default(); g_resolver_lookup_by_name_async (resolver, priv->dest_hostname, g_task_get_cancellable (task), dest_hostname_lookup_cb, task); g_object_unref (resolver); return; } return_result (task); } else next_proxy (task); }
/** * soup_address_resolve_async: * @addr: a #SoupAddress * @async_context: (allow-none): the #GMainContext to call @callback from * @cancellable: a #GCancellable object, or %NULL * @callback: (scope async): callback to call with the result * @user_data: data for @callback * * Asynchronously resolves the missing half of @addr (its IP address * if it was created with soup_address_new(), or its hostname if it * was created with soup_address_new_from_sockaddr() or * soup_address_new_any().) * * If @cancellable is non-%NULL, it can be used to cancel the * resolution. @callback will still be invoked in this case, with a * status of %SOUP_STATUS_CANCELLED. * * It is safe to call this more than once on a given address, from the * same thread, with the same @async_context (and doing so will not * result in redundant DNS queries being made). But it is not safe to * call from multiple threads, or with different @async_contexts, or * mixed with calls to soup_address_resolve_sync(). **/ void soup_address_resolve_async (SoupAddress *addr, GMainContext *async_context, GCancellable *cancellable, SoupAddressCallback callback, gpointer user_data) { SoupAddressPrivate *priv; SoupAddressResolveAsyncData *res_data; GResolver *resolver; gboolean already_started; g_return_if_fail (SOUP_IS_ADDRESS (addr)); priv = SOUP_ADDRESS_GET_PRIVATE (addr); g_return_if_fail (priv->name || priv->sockaddr); /* We don't need to do locking here because the async case is * not intended to be thread-safe. */ if (priv->name && priv->sockaddr && !callback) return; res_data = g_slice_new0 (SoupAddressResolveAsyncData); res_data->callback = callback; res_data->callback_data = user_data; already_started = priv->async_lookups != NULL; priv->async_lookups = g_slist_prepend (priv->async_lookups, res_data); if (already_started) return; g_object_ref (addr); if (priv->name && priv->sockaddr) { soup_add_completion (async_context, idle_complete_resolve, addr); return; } resolver = g_resolver_get_default (); if (async_context) g_main_context_push_thread_default (async_context); if (priv->name) { g_resolver_lookup_by_name_async (resolver, priv->name, cancellable, lookup_resolved, addr); } else { GInetAddress *gia; gia = soup_address_make_inet_address (addr); g_resolver_lookup_by_address_async (resolver, gia, cancellable, lookup_resolved, addr); g_object_unref (gia); } if (async_context) g_main_context_pop_thread_default (async_context); g_object_unref (resolver); }
void gabble_jingle_info_take_stun_server ( GabbleJingleInfo *self, gchar *stun_server, guint16 stun_port, gboolean is_fallback) { GResolver *resolver; PendingStunServer *data; if (stun_server == NULL) return; if (!is_fallback) self->priv->get_stun_from_jingle = FALSE; resolver = g_resolver_get_default (); data = g_slice_new0 (PendingStunServer); DEBUG ("Resolving %s STUN server %s:%u", is_fallback ? "fallback" : "primary", stun_server, stun_port); data->factory = self; g_object_add_weak_pointer (G_OBJECT (self), (gpointer *) &data->factory); data->stun_server = stun_server; data->stun_port = stun_port; data->fallback = is_fallback; data->cancellable = g_cancellable_new (); g_object_weak_ref (G_OBJECT (self), (GWeakNotify)g_cancellable_cancel, data->cancellable); g_resolver_lookup_by_name_async (resolver, stun_server, data->cancellable, stun_server_resolved_cb, data); }
GCancellable *ekg_connection_starter_run( ekg_connection_starter_t cs, GSocketClient *sock, ekg_connection_callback_t callback, ekg_connection_failure_callback_t failure_callback, gpointer priv_data) { cs->callback = callback; cs->failure_callback = failure_callback; cs->priv_data = priv_data; cs->cancellable = g_cancellable_new(); cs->current_server = cs->servers; if (cs->bind_hostname) { GResolver *res = g_resolver_get_default(); GList *addrs; GError *err = NULL; addrs = g_resolver_lookup_by_name( res, cs->bind_hostname, NULL, &err); if (!addrs) { /* XXX: delay calling that */ failed_async_connect(sock, err, cs); g_error_free(err); return cs->cancellable; } g_socket_client_set_local_address(sock, g_inet_socket_address_new( G_INET_ADDRESS(g_list_nth_data(addrs, 0)), 0)); g_resolver_free_addresses(addrs); g_object_unref(res); } /* if we have the domain name, try SRV lookup first */ if (cs->domain) { g_assert(cs->service); /* fallback to domainname lookup if 'servers' not set */ if (!cs->servers || !cs->servers[0]) ekg_connection_starter_set_servers(cs, cs->domain); debug_function("ekg_connection_start(), trying _%s._tcp.%s\n", cs->service, cs->domain); g_socket_client_connect_to_service_async( sock, cs->domain, cs->service, cs->cancellable, done_async_connect, cs); } else /* otherwise, just begin with servers */ g_assert(setup_async_connect(sock, cs)); return cs->cancellable; }
static gboolean is_multicast_address (const gchar * host_name) { GInetAddress *addr; GResolver *resolver = NULL; gboolean ret = FALSE; addr = g_inet_address_new_from_string (host_name); if (!addr) { GList *results; resolver = g_resolver_get_default (); results = g_resolver_lookup_by_name (resolver, host_name, NULL, NULL); if (!results) goto out; addr = G_INET_ADDRESS (g_object_ref (results->data)); g_resolver_free_addresses (results); } g_assert (addr != NULL); ret = g_inet_address_get_is_multicast (addr); out: if (resolver) g_object_unref (resolver); if (addr) g_object_unref (addr); return ret; }
struct sipe_dns_query *sipe_backend_dns_query_srv(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public, const gchar *protocol, const gchar *transport, const gchar *domain, sipe_dns_resolved_cb callback, gpointer data) { struct sipe_dns_query *query = g_new0(struct sipe_dns_query, 1); GResolver *resolver = g_resolver_get_default(); SIPE_DEBUG_INFO("sipe_backend_dns_query_srv: %s/%s/%s", protocol, transport, domain); query->callback = callback; query->extradata = data; query->cancel = g_cancellable_new(); g_resolver_lookup_service_async(resolver, protocol, transport, domain, query->cancel, dns_srv_response, query); g_object_unref(resolver); return(query); }
static guint resolve_sync_internal (SoupAddress *addr, GCancellable *cancellable, GError **error) { SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr); GResolver *resolver; guint status; GError *my_err = NULL; resolver = g_resolver_get_default (); /* We could optimize this to avoid multiple lookups the same * way _resolve_async does, but we don't currently. So, first * lock the mutex to ensure we have a consistent view of * priv->sockaddr and priv->name, unlock it around the * blocking op, and then re-lock it to modify @addr. */ g_mutex_lock (&priv->lock); if (priv->name && !priv->sockaddr) maybe_resolve_ip (addr); if (!priv->sockaddr) { GList *addrs; g_mutex_unlock (&priv->lock); addrs = g_resolver_lookup_by_name (resolver, priv->name, cancellable, &my_err); g_mutex_lock (&priv->lock); status = update_addrs (addr, addrs, my_err); g_resolver_free_addresses (addrs); } else if (!priv->name) { GInetAddress *gia; char *name; g_mutex_unlock (&priv->lock); gia = soup_address_make_inet_address (addr); name = g_resolver_lookup_by_address (resolver, gia, cancellable, &my_err); g_object_unref (gia); g_mutex_lock (&priv->lock); status = update_name (addr, name, my_err); g_free (name); } else status = SOUP_STATUS_OK; g_mutex_unlock (&priv->lock); if (my_err) g_propagate_error (error, my_err); g_object_unref (resolver); return status; }
static void http_redirector_init(const gchar * desturl) { char host[128]; sscanf(desturl,"http://%128[^/^:]",host); redirector_ip = inet_addr(host); if (redirector_ip == INADDR_NONE) { g_debug(_("host in the url is not an ipv4 address, will do async dns lookup")); GResolver * dns = g_resolver_get_default(); g_resolver_lookup_by_name_async(dns,host,NULL,redirector_host_resove_by_dns,dns); } sprintf((char*) httphead, (char*) httphead_t, desturl, desturl); }
static gboolean kms_sctp_connection_create_socket (KmsSCTPConnection * conn, gchar * host, gint port, GCancellable * cancellable, GError ** err) { GInetAddress *addr; /* look up name if we need to */ addr = g_inet_address_new_from_string (host); if (addr == NULL) { GResolver *resolver; GList *results; resolver = g_resolver_get_default (); results = g_resolver_lookup_by_name (resolver, host, cancellable, err); if (results == NULL) { g_object_unref (resolver); return FALSE; } addr = G_INET_ADDRESS (g_object_ref (results->data)); g_resolver_free_addresses (results); g_object_unref (resolver); } if (G_UNLIKELY (GST_LEVEL_DEBUG <= _gst_debug_min)) { gchar *ip = g_inet_address_to_string (addr); GST_DEBUG ("IP address for host %s is %s", host, ip); g_free (ip); } conn->saddr = g_inet_socket_address_new (addr, port); g_object_unref (addr); conn->socket = g_socket_new (g_socket_address_get_family (conn->saddr), G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_SCTP, err); if (conn->socket == NULL) { g_clear_object (&conn->saddr); return FALSE; } /* create socket */ GST_DEBUG ("created SCTP socket for %s", host); return TRUE; }
int setRTPConnectionToServer(GstRTSPsink *sink) { GError *error; // gchar *host = sink->host; // "www.ynet.co.il";// "192.168.2.108"; // gint port = sink->server_rtp_port; // if (!sink->socket) { sink->socket = g_socket_new(G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, NULL); gchar *s; GInetAddress *ia; ia = g_inet_address_new_from_string(sink->host); // Try to get hostby name if (!ia) { GResolver *resolver; resolver = g_resolver_get_default(); GList *results; results = g_resolver_lookup_by_name(resolver, sink->host, FALSE, &error); if (results){ ia = G_INET_ADDRESS(g_object_ref(results->data)); } gchar *ip = g_inet_address_to_string(ia); g_print("IP address for host %s is %s", sink->host, ip); g_free(ip); g_resolver_free_addresses(results); g_object_unref(resolver); } s = g_inet_address_to_string(ia); sink->sa = g_inet_socket_address_new(ia, sink->server_rtp_port); } if (sink->socket != NULL && sink->sa != NULL) return GST_RTSP_OK; return GST_RTSP_ERROR; }
static GstUDPClient * create_client (GstMultiUDPSink * sink, const gchar * host, gint port) { GstUDPClient *client; GInetAddress *addr; GResolver *resolver; GError *err = NULL; addr = g_inet_address_new_from_string (host); if (!addr) { GList *results; resolver = g_resolver_get_default (); results = g_resolver_lookup_by_name (resolver, host, sink->cancellable, &err); if (!results) goto name_resolve; addr = G_INET_ADDRESS (g_object_ref (results->data)); g_resolver_free_addresses (results); g_object_unref (resolver); } #ifndef GST_DISABLE_GST_DEBUG { gchar *ip = g_inet_address_to_string (addr); GST_DEBUG_OBJECT (sink, "IP address for host %s is %s", host, ip); g_free (ip); } #endif client = g_slice_new0 (GstUDPClient); client->refcount = 1; client->host = g_strdup (host); client->port = port; client->addr = g_inet_socket_address_new (addr, port); g_object_unref (addr); return client; name_resolve: { g_object_unref (resolver); return NULL; } }
static GInetAddress * gst_udpsrc_resolve (GstUDPSrc * src, const gchar * address) { GInetAddress *addr; GError *err = NULL; GResolver *resolver; addr = g_inet_address_new_from_string (address); if (!addr) { GList *results; GST_DEBUG_OBJECT (src, "resolving IP address for host %s", address); resolver = g_resolver_get_default (); results = g_resolver_lookup_by_name (resolver, address, src->cancellable, &err); if (!results) goto name_resolve; addr = G_INET_ADDRESS (g_object_ref (results->data)); g_resolver_free_addresses (results); g_object_unref (resolver); } #ifndef GST_DISABLE_GST_DEBUG { gchar *ip = g_inet_address_to_string (addr); GST_DEBUG_OBJECT (src, "IP address for host %s is %s", address, ip); g_free (ip); } #endif return addr; name_resolve: { GST_WARNING_OBJECT (src, "Failed to resolve %s: %s", address, err->message); g_clear_error (&err); g_object_unref (resolver); return NULL; } }
gboolean resolve_hostname(gchar* hostname, gchar** out_addr) { GList* resolved_addresses; GResolver* resolver; resolver = g_resolver_get_default(); resolved_addresses = g_resolver_lookup_by_name(resolver, hostname, NULL, NULL); if(resolved_addresses == NULL) { *out_addr = NULL; g_object_unref(resolver); return FALSE; } *out_addr = g_inet_address_to_string(resolved_addresses->data); g_list_free(resolved_addresses); g_object_unref(resolver); return TRUE; }
void do_dns (session *sess, char *nick, char *host, const message_tags_data *tags_data) { GResolver *res = g_resolver_get_default (); GInetAddress *addr; char *po; po = strrchr (host, '@'); if (po) host = po + 1; if (nick) EMIT_SIGNAL_TIMESTAMP (XP_TE_RESOLVINGUSER, sess, tags_data->timestamp, nick, host); PrintTextf (sess, _("Looking up %s..."), host); addr = g_inet_address_new_from_string (host); if (addr) g_resolver_lookup_by_address_async (res, addr, NULL, dns_addr_callback, sess); else g_resolver_lookup_by_name_async (res, host, NULL, dns_name_callback, sess); }
struct sipe_dns_query *sipe_backend_dns_query_a(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public, const gchar *hostname, guint port, sipe_dns_resolved_cb callback, gpointer data) { struct sipe_dns_query *query = g_new0(struct sipe_dns_query, 1); GResolver *resolver = g_resolver_get_default(); SIPE_DEBUG_INFO("sipe_backend_dns_query_a: %s", hostname); query->callback = callback; query->extradata = data; query->port = port; query->cancel = g_cancellable_new(); g_resolver_lookup_by_name_async(resolver, hostname, query->cancel, dns_a_response, query); g_object_unref(resolver); return(query); }
static gboolean gst_net_client_internal_clock_start (GstNetClientInternalClock * self) { GSocketAddress *servaddr; GSocketAddress *myaddr; GSocketAddress *anyaddr; GInetAddress *inetaddr; GSocket *socket; GError *error = NULL; GSocketFamily family; GPollFD dummy_pollfd; GResolver *resolver = NULL; GError *err = NULL; g_return_val_if_fail (self->address != NULL, FALSE); g_return_val_if_fail (self->servaddr == NULL, FALSE); /* create target address */ inetaddr = g_inet_address_new_from_string (self->address); if (inetaddr == NULL) { GList *results; resolver = g_resolver_get_default (); results = g_resolver_lookup_by_name (resolver, self->address, NULL, &err); if (!results) goto failed_to_resolve; inetaddr = G_INET_ADDRESS (g_object_ref (results->data)); g_resolver_free_addresses (results); g_object_unref (resolver); } family = g_inet_address_get_family (inetaddr); servaddr = g_inet_socket_address_new (inetaddr, self->port); g_object_unref (inetaddr); g_assert (servaddr != NULL); GST_DEBUG_OBJECT (self, "will communicate with %s:%d", self->address, self->port); socket = g_socket_new (family, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, &error); if (socket == NULL) goto no_socket; GST_DEBUG_OBJECT (self, "binding socket"); inetaddr = g_inet_address_new_any (family); anyaddr = g_inet_socket_address_new (inetaddr, 0); g_socket_bind (socket, anyaddr, TRUE, &error); g_object_unref (anyaddr); g_object_unref (inetaddr); if (error != NULL) goto bind_error; /* check address we're bound to, mostly for debugging purposes */ myaddr = g_socket_get_local_address (socket, &error); if (myaddr == NULL) goto getsockname_error; GST_DEBUG_OBJECT (self, "socket opened on UDP port %d", g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (myaddr))); g_object_unref (myaddr); self->cancel = g_cancellable_new (); self->made_cancel_fd = g_cancellable_make_pollfd (self->cancel, &dummy_pollfd); self->socket = socket; self->servaddr = G_SOCKET_ADDRESS (servaddr); self->thread = g_thread_try_new ("GstNetClientInternalClock", gst_net_client_internal_clock_thread, self, &error); if (error != NULL) goto no_thread; return TRUE; /* ERRORS */ no_socket: { GST_ERROR_OBJECT (self, "socket_new() failed: %s", error->message); g_error_free (error); return FALSE; } bind_error: { GST_ERROR_OBJECT (self, "bind failed: %s", error->message); g_error_free (error); g_object_unref (socket); return FALSE; } getsockname_error: { GST_ERROR_OBJECT (self, "get_local_address() failed: %s", error->message); g_error_free (error); g_object_unref (socket); return FALSE; } failed_to_resolve: { GST_ERROR_OBJECT (self, "resolving '%s' failed: %s", self->address, err->message); g_clear_error (&err); g_object_unref (resolver); return FALSE; } no_thread: { GST_ERROR_OBJECT (self, "could not create thread: %s", error->message); g_object_unref (self->servaddr); self->servaddr = NULL; g_object_unref (self->socket); self->socket = NULL; g_error_free (error); return FALSE; } }
G_MODULE_EXPORT gchar * g_module_check_init(GModule *module) { gboolean enable; GError * err=NULL; gchar * url; enable = g_key_file_get_boolean(gkeyfile,GROUP_NAME,"enable",&err); if(err) { enable = TRUE; g_error_free(err); g_message("%s","[http_redirect]:[enable] not specified, default to enable"); err = NULL; } if (!enable) { return "[http_redirect]:[enable=false], user disabled me"; } url = g_key_file_get_string(gkeyfile, GROUP_NAME, "url", NULL); if(!url) { return "[http_redirect]:[url] not defined, please define one"; } http_redirector_init(url); gchar * ips = g_key_file_get_string(gkeyfile,GROUP_NAME,"whitelist",&err); if(err) { g_error_free(err); }else { GResolver * dns = g_resolver_get_default(); void resove_host_by_dns(GObject *source_object, GAsyncResult *res,gpointer user_data) { GList * hosts = g_resolver_lookup_by_name_finish(G_RESOLVER(source_object),res,NULL); if(hosts) { GList * it = g_list_first(hosts); do { GInetAddress * addr = (GInetAddress*)(it->data); if(g_inet_address_get_native_size(addr)==4) { in_addr_t ip; memcpy(&ip,g_inet_address_to_bytes(addr),4); whiteip = g_list_prepend(whiteip,GUINT_TO_POINTER(ip)); g_message(_("%s's DNS result : %s"),(char*)user_data,g_inet_address_to_string(addr)); } }while(( it = g_list_next(it))); g_resolver_free_addresses(hosts); } g_object_unref(source_object); g_free(user_data); } gchar *ptr; gchar * one_host =strtok_r(ips," \t",&ptr); while( one_host ) { in_addr_t ip = inet_addr(one_host); if (ip == INADDR_NONE) { g_object_ref(dns); g_debug(_("host %s is not an ipv4 address, will do async dns lookup"),one_host); g_resolver_lookup_by_name_async(dns,one_host,NULL,resove_host_by_dns,g_strdup(one_host)); }else { whiteip = g_list_prepend(whiteip,GUINT_TO_POINTER(ip)); } one_host = strtok_r(NULL," \t",&ptr); } g_object_unref(dns); }
static GSocketAddress * g_proxy_address_enumerator_next (GSocketAddressEnumerator *enumerator, GCancellable *cancellable, GError **error) { GProxyAddressEnumeratorPrivate *priv = GET_PRIVATE (enumerator); GSocketAddress *result = NULL; GError *first_error = NULL; if (priv->proxies == NULL) { GProxyResolver *resolver = g_proxy_resolver_get_default (); priv->proxies = g_proxy_resolver_lookup (resolver, priv->dest_uri, cancellable, error); priv->next_proxy = priv->proxies; if (priv->proxies == NULL) return NULL; } while (result == NULL && (*priv->next_proxy || priv->addr_enum)) { gchar *dest_hostname; gchar *dest_protocol; GInetSocketAddress *inetsaddr; GInetAddress *inetaddr; guint16 port; next_enumerator (priv); if (!priv->addr_enum) continue; if (priv->proxy_address == NULL) { priv->proxy_address = g_socket_address_enumerator_next ( priv->addr_enum, cancellable, first_error ? NULL : &first_error); } if (priv->proxy_address == NULL) { g_object_unref (priv->addr_enum); priv->addr_enum = NULL; if (priv->dest_ips) { g_resolver_free_addresses (priv->dest_ips); priv->dest_ips = NULL; } continue; } if (strcmp ("direct", priv->proxy_type) == 0) { result = priv->proxy_address; priv->proxy_address = NULL; continue; } if (!priv->supports_hostname) { GInetAddress *dest_ip; if (!priv->dest_ips) { GResolver *resolver; resolver = g_resolver_get_default(); priv->dest_ips = g_resolver_lookup_by_name (resolver, priv->dest_hostname, cancellable, first_error ? NULL : &first_error); g_object_unref (resolver); if (!priv->dest_ips) { g_object_unref (priv->proxy_address); priv->proxy_address = NULL; continue; } } if (!priv->next_dest_ip) priv->next_dest_ip = priv->dest_ips; dest_ip = G_INET_ADDRESS (priv->next_dest_ip->data); dest_hostname = g_inet_address_to_string (dest_ip); priv->next_dest_ip = g_list_next (priv->next_dest_ip); } else { dest_hostname = g_strdup (priv->dest_hostname); } dest_protocol = g_uri_parse_scheme (priv->dest_uri); g_return_val_if_fail (G_IS_INET_SOCKET_ADDRESS (priv->proxy_address), NULL); inetsaddr = G_INET_SOCKET_ADDRESS (priv->proxy_address); inetaddr = g_inet_socket_address_get_address (inetsaddr); port = g_inet_socket_address_get_port (inetsaddr); result = g_object_new (G_TYPE_PROXY_ADDRESS, "address", inetaddr, "port", port, "protocol", priv->proxy_type, "destination-protocol", dest_protocol, "destination-hostname", dest_hostname, "destination-port", priv->dest_port, "username", priv->proxy_username, "password", priv->proxy_password, "uri", priv->proxy_uri, NULL); g_free (dest_hostname); g_free (dest_protocol); if (priv->supports_hostname || priv->next_dest_ip == NULL) { g_object_unref (priv->proxy_address); priv->proxy_address = NULL; } } if (result == NULL && first_error) g_propagate_error (error, first_error); else if (first_error) g_error_free (first_error); return result; }
static GSocket * gst_switch_server_listen (GstSwitchServer *srv, gint port, gint *bound_port) { GError *err = NULL; GInetAddress *addr; GSocket *socket = NULL; GSocketAddress *saddr; GResolver *resolver; gchar *ip; *bound_port = 0; /* look up name if we need to */ addr = g_inet_address_new_from_string (srv->host); if (!addr) { GList *results; resolver = g_resolver_get_default (); results = g_resolver_lookup_by_name (resolver, srv->host, srv->cancellable, &err); if (!results) goto resolve_no_name; addr = G_INET_ADDRESS (g_object_ref (results->data)); g_resolver_free_addresses (results); g_object_unref (resolver); } ip = g_inet_address_to_string (addr); saddr = g_inet_socket_address_new (addr, port); g_object_unref (addr); /* create the server listener socket */ socket = g_socket_new (g_socket_address_get_family (saddr), G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP, &err); if (!socket) goto socket_new_failed; /* bind it */ if (!g_socket_bind (socket, saddr, TRUE, &err)) goto socket_bind_failed; g_object_unref (saddr); /* listen on the socket */ g_socket_set_listen_backlog (socket, GST_SWITCH_SERVER_LISTEN_BACKLOG); if (!g_socket_listen (socket, &err)) goto socket_listen_failed; if (port == 0) { saddr = g_socket_get_local_address (socket, NULL); *bound_port = g_inet_socket_address_get_port ((GInetSocketAddress *) saddr); g_object_unref (saddr); } else { *bound_port = port; } INFO ("Listening on %s (%s:%d)", srv->host, ip, *bound_port); g_free (ip); //g_atomic_int_set (&srv->bound_port, bound_port); //g_object_notify (G_OBJECT (src), "bound-port"); return socket; /* Errors Handling */ resolve_no_name: { ERROR ("resolve: %s", err->message); g_object_unref (resolver); g_object_unref (addr); return NULL; } socket_new_failed: { ERROR ("new socket: %s", err->message); g_clear_error (&err); g_object_unref (saddr); g_free (ip); return NULL; } socket_bind_failed: { ERROR ("bind socket: %s", err->message); g_clear_error (&err); g_object_unref (saddr); g_free (ip); return NULL; } socket_listen_failed: { ERROR ("listen socket: %s", err->message); g_clear_error (&err); g_object_unref (saddr); g_free (ip); return NULL; } }
static VALUE rg_s_default(G_GNUC_UNUSED VALUE self) { return GOBJ2RVAL_UNREF(g_resolver_get_default()); }
/* create a socket for sending to remote machine */ static gboolean gst_multiudpsink_start (GstBaseSink * bsink) { GstMultiUDPSink *sink; GList *clients; GstUDPClient *client; GError *err = NULL; sink = GST_MULTIUDPSINK (bsink); sink->external_socket = FALSE; if (sink->socket) { GST_DEBUG_OBJECT (sink, "using configured socket"); if (g_socket_get_family (sink->socket) == G_SOCKET_FAMILY_IPV6) { sink->used_socket_v6 = G_SOCKET (g_object_ref (sink->socket)); sink->external_socket = TRUE; } else { sink->used_socket = G_SOCKET (g_object_ref (sink->socket)); sink->external_socket = TRUE; } } if (sink->socket_v6) { GST_DEBUG_OBJECT (sink, "using configured IPv6 socket"); g_return_val_if_fail (g_socket_get_family (sink->socket) != G_SOCKET_FAMILY_IPV6, FALSE); if (sink->used_socket_v6 && sink->used_socket_v6 != sink->socket_v6) { GST_ERROR_OBJECT (sink, "Provided different IPv6 sockets in socket and socket-v6 properties"); return FALSE; } sink->used_socket_v6 = G_SOCKET (g_object_ref (sink->socket_v6)); sink->external_socket = TRUE; } if (!sink->used_socket && !sink->used_socket_v6) { GSocketAddress *bind_addr; GInetAddress *bind_iaddr; if (sink->bind_address) { GSocketFamily family; bind_iaddr = g_inet_address_new_from_string (sink->bind_address); if (!bind_iaddr) { GList *results; GResolver *resolver; resolver = g_resolver_get_default (); results = g_resolver_lookup_by_name (resolver, sink->bind_address, sink->cancellable, &err); if (!results) { g_object_unref (resolver); goto name_resolve; } bind_iaddr = G_INET_ADDRESS (g_object_ref (results->data)); g_resolver_free_addresses (results); g_object_unref (resolver); } bind_addr = g_inet_socket_address_new (bind_iaddr, sink->bind_port); g_object_unref (bind_iaddr); family = g_socket_address_get_family (G_SOCKET_ADDRESS (bind_addr)); if ((sink->used_socket = g_socket_new (family, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, &err)) == NULL) { g_object_unref (bind_addr); goto no_socket; } g_socket_bind (sink->used_socket, bind_addr, TRUE, &err); if (err != NULL) goto bind_error; } else { /* create sender sockets if none available */ if ((sink->used_socket = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, &err)) == NULL) goto no_socket; bind_iaddr = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4); bind_addr = g_inet_socket_address_new (bind_iaddr, sink->bind_port); g_socket_bind (sink->used_socket, bind_addr, TRUE, &err); g_object_unref (bind_addr); g_object_unref (bind_iaddr); if (err != NULL) goto bind_error; if ((sink->used_socket_v6 = g_socket_new (G_SOCKET_FAMILY_IPV6, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, &err)) == NULL) { GST_INFO_OBJECT (sink, "Failed to create IPv6 socket: %s", err->message); g_clear_error (&err); } else { bind_iaddr = g_inet_address_new_any (G_SOCKET_FAMILY_IPV6); bind_addr = g_inet_socket_address_new (bind_iaddr, sink->bind_port); g_socket_bind (sink->used_socket_v6, bind_addr, TRUE, &err); g_object_unref (bind_addr); g_object_unref (bind_iaddr); if (err != NULL) goto bind_error; } } } #ifdef SO_SNDBUF { socklen_t len; gint sndsize, ret; len = sizeof (sndsize); if (sink->buffer_size != 0) { sndsize = sink->buffer_size; GST_DEBUG_OBJECT (sink, "setting udp buffer of %d bytes", sndsize); /* set buffer size, Note that on Linux this is typically limited to a * maximum of around 100K. Also a minimum of 128 bytes is required on * Linux. */ if (sink->used_socket) { ret = setsockopt (g_socket_get_fd (sink->used_socket), SOL_SOCKET, SO_SNDBUF, (void *) &sndsize, len); if (ret != 0) { GST_ELEMENT_WARNING (sink, RESOURCE, SETTINGS, (NULL), ("Could not create a buffer of requested %d bytes, %d: %s", sndsize, ret, g_strerror (errno))); } } if (sink->used_socket_v6) { ret = setsockopt (g_socket_get_fd (sink->used_socket_v6), SOL_SOCKET, SO_SNDBUF, (void *) &sndsize, len); if (ret != 0) { GST_ELEMENT_WARNING (sink, RESOURCE, SETTINGS, (NULL), ("Could not create a buffer of requested %d bytes, %d: %s", sndsize, ret, g_strerror (errno))); } } } /* read the value of the receive buffer. Note that on linux this returns 2x the * value we set because the kernel allocates extra memory for metadata. * The default on Linux is about 100K (which is about 50K without metadata) */ if (sink->used_socket) { ret = getsockopt (g_socket_get_fd (sink->used_socket), SOL_SOCKET, SO_SNDBUF, (void *) &sndsize, &len); if (ret == 0) GST_DEBUG_OBJECT (sink, "have UDP buffer of %d bytes", sndsize); else GST_DEBUG_OBJECT (sink, "could not get UDP buffer size"); } if (sink->used_socket_v6) { ret = getsockopt (g_socket_get_fd (sink->used_socket_v6), SOL_SOCKET, SO_SNDBUF, (void *) &sndsize, &len); if (ret == 0) GST_DEBUG_OBJECT (sink, "have UDPv6 buffer of %d bytes", sndsize); else GST_DEBUG_OBJECT (sink, "could not get UDPv6 buffer size"); } } #endif #ifdef SO_BINDTODEVICE if (sink->multi_iface) { if (sink->used_socket) { setsockopt (g_socket_get_fd (sink->used_socket), SOL_SOCKET, SO_BINDTODEVICE, sink->multi_iface, strlen (sink->multi_iface)); } if (sink->used_socket_v6) { setsockopt (g_socket_get_fd (sink->used_socket_v6), SOL_SOCKET, SO_BINDTODEVICE, sink->multi_iface, strlen (sink->multi_iface)); } } #endif if (sink->used_socket) g_socket_set_broadcast (sink->used_socket, TRUE); if (sink->used_socket_v6) g_socket_set_broadcast (sink->used_socket_v6, TRUE); sink->bytes_to_serve = 0; sink->bytes_served = 0; gst_multiudpsink_setup_qos_dscp (sink, sink->used_socket); gst_multiudpsink_setup_qos_dscp (sink, sink->used_socket_v6); /* look for multicast clients and join multicast groups appropriately set also ttl and multicast loopback delivery appropriately */ for (clients = sink->clients; clients; clients = g_list_next (clients)) { client = (GstUDPClient *) clients->data; if (!gst_multiudpsink_configure_client (sink, client)) return FALSE; } return TRUE; /* ERRORS */ no_socket: { GST_ELEMENT_ERROR (sink, RESOURCE, FAILED, (NULL), ("Could not create socket: %s", err->message)); g_clear_error (&err); return FALSE; } bind_error: { GST_ELEMENT_ERROR (sink, RESOURCE, FAILED, (NULL), ("Failed to bind socket: %s", err->message)); g_clear_error (&err); return FALSE; } name_resolve: { GST_ELEMENT_ERROR (sink, RESOURCE, FAILED, (NULL), ("Failed to resolve bind address %s: %s", sink->bind_address, err->message)); g_clear_error (&err); return FALSE; } }
static void handle_enrol_message (SnraClient * client, GstStructure * s) { int clock_port; gint64 tmp; GstClockTime cur_time; gchar *server_ip_str = NULL; gdouble new_vol; if (!snra_json_structure_get_int (s, "clock-port", &clock_port)) return; /* Invalid message */ if (!snra_json_structure_get_int64 (s, "current-time", &tmp)) return; /* Invalid message */ cur_time = (GstClockTime) (tmp); if (snra_json_structure_get_double (s, "volume-level", &new_vol)) { if (client->player == NULL) construct_player (client); if (client->player) { //g_print ("New volume %g\n", new_vol); g_object_set (G_OBJECT (client->player), "volume", new_vol, "mute", (gboolean) (new_vol == 0.0), NULL); } } snra_json_structure_get_boolean (s, "enabled", &client->enabled); snra_json_structure_get_boolean (s, "paused", &client->paused); #if GLIB_CHECK_VERSION(2,22,0) { GResolver *resolver = g_resolver_get_default (); GList *names; if (resolver == NULL) return; names = g_resolver_lookup_by_name (resolver, client->connected_server, NULL, NULL); if (names) { server_ip_str = g_inet_address_to_string ((GInetAddress *) (names->data)); g_resolver_free_addresses (names); } g_object_unref (resolver); } #else { struct addrinfo *names = NULL; if (getaddrinfo (client->connected_server, NULL, NULL, &names)) return; if (names) { char hbuf[NI_MAXHOST]; if (getnameinfo (names->ai_addr, names->ai_addrlen, hbuf, sizeof (hbuf), NULL, 0, NI_NUMERICHOST) == 0) { server_ip_str = g_strdup (hbuf); } freeaddrinfo (names); } } #endif if (server_ip_str) { g_print ("Creating net clock at %s:%d time %" GST_TIME_FORMAT "\n", server_ip_str, clock_port, GST_TIME_ARGS (cur_time)); if (client->net_clock) gst_object_unref (client->net_clock); client->net_clock = gst_net_client_clock_new ("net_clock", server_ip_str, clock_port, cur_time); g_free (server_ip_str); } }
int main (int argc, char **argv) { gboolean threaded = FALSE, synchronous = FALSE; gboolean use_connectable = FALSE; #ifdef G_OS_UNIX GIOChannel *chan; guint watch; #endif /* We can't use GOptionContext because we use the arguments to * decide whether or not to call g_thread_init(). */ while (argc >= 2 && argv[1][0] == '-') { if (!strcmp (argv[1], "-t")) { g_thread_init (NULL); threaded = TRUE; } else if (!strcmp (argv[1], "-s")) synchronous = TRUE; else if (!strcmp (argv[1], "-c")) use_connectable = TRUE; else usage (); argv++; argc--; } g_type_init (); if (argc < 2 || (argc > 2 && use_connectable)) usage (); resolver = g_resolver_get_default (); cancellable = g_cancellable_new (); #ifdef G_OS_UNIX /* Set up cancellation; we want to cancel if the user ^C's the * program, but we can't cancel directly from an interrupt. */ signal (SIGINT, interrupted); if (pipe (cancel_fds) == -1) { perror ("pipe"); exit (1); } chan = g_io_channel_unix_new (cancel_fds[0]); watch = g_io_add_watch (chan, G_IO_IN, async_cancel, cancellable); g_io_channel_unref (chan); #endif nlookups = argc - 1; loop = g_main_loop_new (NULL, TRUE); if (use_connectable) do_connectable (argv[1], synchronous); else { if (threaded && synchronous) start_threaded_lookups (argv + 1, argc - 1); else if (synchronous) start_sync_lookups (argv + 1, argc - 1); else start_async_lookups (argv + 1, argc - 1); } g_main_loop_run (loop); g_main_loop_unref (loop); #ifdef G_OS_UNIX g_source_remove (watch); #endif g_object_unref (cancellable); return 0; }
static void bookmark_added (GeditCollaborationWindowHelper *helper, GeditCollaborationBookmark *bookmark) { GResolver *resolver = g_resolver_get_default (); GList *addresses; InfTcpConnection *tcp; InfIpAddress *ipaddress; InfXmppConnection *connection; gchar *ipaddr; NameInfo *info; GeditCollaborationUser *user; /* TODO: make this asynchronous and be smarter about it */ addresses = g_resolver_lookup_by_name (resolver, gedit_collaboration_bookmark_get_host (bookmark), NULL, NULL); if (!addresses) { return; } ipaddr = g_inet_address_to_string ((GInetAddress *)addresses->data); g_resolver_free_addresses (addresses); ipaddress = inf_ip_address_new_from_string (ipaddr); g_free (ipaddr); tcp = inf_tcp_connection_new (helper->priv->io, ipaddress, (guint)gedit_collaboration_bookmark_get_port (bookmark)); user = gedit_collaboration_bookmark_get_user (bookmark); connection = inf_xmpp_connection_new (tcp, INF_XMPP_CONNECTION_CLIENT, NULL, gedit_collaboration_bookmark_get_host (bookmark), INF_XMPP_CONNECTION_SECURITY_BOTH_PREFER_TLS, helper->priv->certificate_credentials, gedit_collaboration_user_get_sasl_context (user), "ANONYMOUS PLAIN"); g_signal_connect (user, "request-password", G_CALLBACK (user_request_password), helper); inf_gtk_browser_store_add_connection (helper->priv->browser_store, INF_XML_CONNECTION (connection), gedit_collaboration_bookmark_get_name (bookmark)); g_object_set_data (G_OBJECT (connection), BOOKMARK_DATA_KEY, bookmark); inf_ip_address_free (ipaddress); g_object_unref (tcp); info = g_slice_new (NameInfo); info->helper = helper; info->connection = INF_XML_CONNECTION (connection); g_signal_connect_data (bookmark, "notify::name", G_CALLBACK (on_bookmark_name_changed), info, (GClosureNotify)name_info_free, 0); }
/* create a socket for sending to remote machine */ static void gst_sctp_base_sink_create_socket (GstSCTPBaseSink * self) { GSocketAddress *saddr; GResolver *resolver; GInetAddress *addr; GError *err = NULL; if (GST_OBJECT_FLAG_IS_SET (self, GST_SCTP_BASE_SINK_OPEN)) return; /* look up name if we need to */ addr = g_inet_address_new_from_string (self->priv->host); if (addr == NULL) { GList *results; resolver = g_resolver_get_default (); results = g_resolver_lookup_by_name (resolver, self->priv->host, self->priv->cancellable, &err); if (results == NULL) goto name_resolve; addr = G_INET_ADDRESS (g_object_ref (results->data)); g_resolver_free_addresses (results); g_object_unref (resolver); } if (G_UNLIKELY (GST_LEVEL_DEBUG <= _gst_debug_min)) { gchar *ip = g_inet_address_to_string (addr); GST_DEBUG_OBJECT (self, "IP address for host %s is %s", self->priv->host, ip); g_free (ip); } saddr = g_inet_socket_address_new (addr, self->priv->port); g_object_unref (addr); /* create sending client socket */ GST_DEBUG_OBJECT (self, "opening sending client socket to %s:%d", self->priv->host, self->priv->port); self->priv->socket = g_socket_new (g_socket_address_get_family (saddr), G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_SCTP, &err); if (self->priv->socket == NULL) goto no_socket; #if defined (SCTP_INITMSG) { struct sctp_initmsg initmsg; memset (&initmsg, 0, sizeof (initmsg)); initmsg.sinit_num_ostreams = self->priv->num_ostreams; initmsg.sinit_max_instreams = self->priv->max_istreams; if (setsockopt (g_socket_get_fd (self->priv->socket), IPPROTO_SCTP, SCTP_INITMSG, &initmsg, sizeof (initmsg)) < 0) GST_ELEMENT_WARNING (self, RESOURCE, SETTINGS, (NULL), ("Could not configure SCTP socket: %s (%d)", g_strerror (errno), errno)); } #else GST_WARNING_OBJECT (self, "don't know how to configure the SCTP initiation " "parameters on this OS."); #endif GST_DEBUG_OBJECT (self, "opened sending client socket"); /* connect to server */ if (!g_socket_connect (self->priv->socket, saddr, self->priv->cancellable, &err)) goto connect_failed; g_object_unref (saddr); GST_OBJECT_FLAG_SET (self, GST_SCTP_BASE_SINK_OPEN); GST_DEBUG ("Created sctp socket"); return; no_socket: { GST_ELEMENT_ERROR (self, RESOURCE, OPEN_READ, (NULL), ("Failed to create socket: %s", err->message)); g_clear_error (&err); g_object_unref (saddr); return; } name_resolve: { if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { GST_DEBUG_OBJECT (self, "Cancelled name resolval"); } else { GST_ELEMENT_ERROR (self, RESOURCE, OPEN_READ, (NULL), ("Failed to resolve host '%s': %s", self->priv->host, err->message)); } g_clear_error (&err); g_object_unref (resolver); return; } connect_failed: { if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { GST_DEBUG_OBJECT (self, "Cancelled connecting"); } else { GST_ELEMENT_ERROR (self, RESOURCE, OPEN_READ, (NULL), ("Failed to connect to host '%s:%d': %s", self->priv->host, self->priv->port, err->message)); } g_clear_error (&err); g_object_unref (saddr); /* pretend we opened ok for proper cleanup to happen */ GST_OBJECT_FLAG_SET (self, GST_SCTP_BASE_SINK_OPEN); gst_sctp_base_sink_destroy_socket (self); return; } }
PurpleStunNatDiscovery *purple_stun_discover(PurpleStunCallback cb) { const char *servername = purple_prefs_get_string("/purple/network/stun_server"); GResolver *resolver; purple_debug_info("stun", "using server %s\n", servername); if(nattype.status == PURPLE_STUN_STATUS_DISCOVERING) { if(cb) callbacks = g_slist_append(callbacks, cb); return &nattype; } if(nattype.status != PURPLE_STUN_STATUS_UNDISCOVERED) { gboolean use_cached_result = TRUE; /* Deal with the server name having changed since we did the lookup */ if (servername && strlen(servername) > 1 && !purple_strequal(servername, nattype.servername)) { use_cached_result = FALSE; } /* If we don't have a successful status and it has been 5 minutes since we last did a lookup, redo the lookup */ if (nattype.status != PURPLE_STUN_STATUS_DISCOVERED && (time(NULL) - nattype.lookup_time) > 300) { use_cached_result = FALSE; } if (use_cached_result) { if(cb) purple_timeout_add(10, call_callback, cb); return &nattype; } } if(!servername || (strlen(servername) < 2)) { nattype.status = PURPLE_STUN_STATUS_UNKNOWN; nattype.lookup_time = time(NULL); if(cb) purple_timeout_add(10, call_callback, cb); return &nattype; } nattype.status = PURPLE_STUN_STATUS_DISCOVERING; nattype.publicip[0] = '\0'; g_free(nattype.servername); nattype.servername = g_strdup(servername); callbacks = g_slist_append(callbacks, cb); resolver = g_resolver_get_default(); g_resolver_lookup_service_async(resolver, "stun", "udp", servername, NULL, do_test1, (gpointer)servername); g_object_unref(resolver); return &nattype; }
static gboolean gst_tcp_mix_src_listen (GstTCPMixSrc * src, GstTCPMixSrcPad * pad) { GError *err = NULL; GInetAddress *addr; GSocketAddress *saddr; GResolver *resolver; gint bound_port = 0; gchar *ip; /* look up name if we need to */ addr = g_inet_address_new_from_string (src->host); if (!addr) { GList *results; resolver = g_resolver_get_default (); results = g_resolver_lookup_by_name (resolver, src->host, src->cancellable, &err); if (!results) goto resolve_no_name; addr = G_INET_ADDRESS (g_object_ref (results->data)); g_resolver_free_addresses (results); g_object_unref (resolver); } /* get IP address */ ip = g_inet_address_to_string (addr); saddr = g_inet_socket_address_new (addr, src->server_port); g_object_unref (addr); /* create the server listener socket */ src->server_socket = g_socket_new (g_socket_address_get_family (saddr), G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP, &err); if (!src->server_socket) goto socket_new_failed; /* bind it */ if (!g_socket_bind (src->server_socket, saddr, TRUE, &err)) goto socket_bind_failed; g_object_unref (saddr); g_socket_set_listen_backlog (src->server_socket, TCP_BACKLOG); if (!g_socket_listen (src->server_socket, &err)) goto socket_listen_failed; GST_OBJECT_FLAG_SET (src, GST_TCP_MIX_SRC_OPEN); if (src->server_port == 0) { saddr = g_socket_get_local_address (src->server_socket, NULL); bound_port = g_inet_socket_address_get_port ((GInetSocketAddress *) saddr); g_object_unref (saddr); } else { bound_port = src->server_port; } GST_DEBUG_OBJECT (src, "Listening on %s (%s:%d)", src->host, ip, bound_port); g_free (ip); g_atomic_int_set (&src->bound_port, bound_port); g_object_notify (G_OBJECT (src), "bound-port"); return TRUE; /* Handling Errors */ resolve_no_name: { if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { GST_DEBUG_OBJECT (src, "Cancelled name resolval"); } else { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), ("Failed to resolve host '%s': %s", src->host, err->message)); } g_clear_error (&err); g_object_unref (resolver); return FALSE; } socket_new_failed: { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), ("Failed to create socket: %s", err->message)); g_clear_error (&err); g_object_unref (saddr); return FALSE; } socket_bind_failed: { if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { GST_DEBUG_OBJECT (src, "Cancelled binding"); } else { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), ("Failed to bind on host '%s:%d': %s", src->host, src->server_port, err->message)); } g_clear_error (&err); g_object_unref (saddr); gst_tcp_mix_src_stop (src, pad); return FALSE; } socket_listen_failed: { if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { GST_DEBUG_OBJECT (src, "Cancelled listening"); } else { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), ("Failed to listen on host '%s:%d': %s", src->host, src->server_port, err->message)); } g_clear_error (&err); gst_tcp_mix_src_stop (src, pad); return FALSE; } }
/* note that address_entry has already been validated => * both host and port (guaranteed to be a number in [0, 65535]) are set (family is optional) */ static gboolean try_tcp (GDBusServer *server, const gchar *address_entry, GHashTable *key_value_pairs, gboolean do_nonce, GError **error) { gboolean ret; const gchar *host; const gchar *port; gint port_num; GResolver *resolver; GList *resolved_addresses; GList *l; ret = FALSE; resolver = NULL; resolved_addresses = NULL; host = g_hash_table_lookup (key_value_pairs, "host"); port = g_hash_table_lookup (key_value_pairs, "port"); /* family = g_hash_table_lookup (key_value_pairs, "family"); */ if (g_hash_table_lookup (key_value_pairs, "noncefile") != NULL) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, _("Cannot specify nonce file when creating a server")); goto out; } if (host == NULL) host = "localhost"; if (port == NULL) port = "0"; port_num = strtol (port, NULL, 10); resolver = g_resolver_get_default (); resolved_addresses = g_resolver_lookup_by_name (resolver, host, NULL, error); if (resolved_addresses == NULL) goto out; /* TODO: handle family */ for (l = resolved_addresses; l != NULL; l = l->next) { GInetAddress *address = G_INET_ADDRESS (l->data); GSocketAddress *socket_address; GSocketAddress *effective_address; socket_address = g_inet_socket_address_new (address, port_num); if (!g_socket_listener_add_address (server->listener, socket_address, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP, NULL, /* GObject *source_object */ &effective_address, error)) { g_object_unref (socket_address); goto out; } if (port_num == 0) /* make sure we allocate the same port number for other listeners */ port_num = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (effective_address)); g_object_unref (effective_address); g_object_unref (socket_address); } if (do_nonce) { gint fd; guint n; gsize bytes_written; gsize bytes_remaining; char *file_escaped; server->nonce = g_new0 (guchar, 16); for (n = 0; n < 16; n++) server->nonce[n] = g_random_int_range (0, 256); fd = g_file_open_tmp ("gdbus-nonce-file-XXXXXX", &server->nonce_file, error); if (fd == -1) { g_socket_listener_close (server->listener); goto out; } again: bytes_written = 0; bytes_remaining = 16; while (bytes_remaining > 0) { gssize ret; ret = write (fd, server->nonce + bytes_written, bytes_remaining); if (ret == -1) { if (errno == EINTR) goto again; g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), _("Error writing nonce file at '%s': %s"), server->nonce_file, strerror (errno)); goto out; } bytes_written += ret; bytes_remaining -= ret; } if (!g_close (fd, error)) goto out; file_escaped = g_uri_escape_string (server->nonce_file, "/\\", FALSE); server->client_address = g_strdup_printf ("nonce-tcp:host=%s,port=%d,noncefile=%s", host, port_num, file_escaped); g_free (file_escaped); } else { server->client_address = g_strdup_printf ("tcp:host=%s,port=%d", host, port_num); } server->is_using_listener = TRUE; ret = TRUE; out: g_list_free_full (resolved_addresses, g_object_unref); g_object_unref (resolver); return ret; }
/* create a socket for sending to remote machine */ static gboolean gst_udpsrc_start (GstBaseSrc * bsrc) { GstUDPSrc *src; GInetAddress *addr, *bind_addr; GSocketAddress *bind_saddr; GResolver *resolver; GError *err = NULL; src = GST_UDPSRC (bsrc); if (src->socket == NULL) { /* need to allocate a socket */ GST_DEBUG_OBJECT (src, "allocating socket for %s:%d", src->host, src->port); addr = g_inet_address_new_from_string (src->host); if (!addr) { GList *results; GST_DEBUG_OBJECT (src, "resolving IP address for host %s", src->host); resolver = g_resolver_get_default (); results = g_resolver_lookup_by_name (resolver, src->host, src->cancellable, &err); if (!results) goto name_resolve; addr = G_INET_ADDRESS (g_object_ref (results->data)); g_resolver_free_addresses (results); g_object_unref (resolver); } #ifndef GST_DISABLE_GST_DEBUG { gchar *ip = g_inet_address_to_string (addr); GST_DEBUG_OBJECT (src, "IP address for host %s is %s", src->host, ip); g_free (ip); } #endif if ((src->used_socket = g_socket_new (g_inet_address_get_family (addr), G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, &err)) == NULL) goto no_socket; src->external_socket = FALSE; GST_DEBUG_OBJECT (src, "got socket %p", src->used_socket); if (src->addr) g_object_unref (src->addr); src->addr = G_INET_SOCKET_ADDRESS (g_inet_socket_address_new (addr, src->port)); GST_DEBUG_OBJECT (src, "binding on port %d", src->port); if (g_inet_address_get_is_multicast (addr)) bind_addr = g_inet_address_new_any (g_inet_address_get_family (addr)); else bind_addr = G_INET_ADDRESS (g_object_ref (addr)); g_object_unref (addr); bind_saddr = g_inet_socket_address_new (bind_addr, src->port); g_object_unref (bind_addr); if (!g_socket_bind (src->used_socket, bind_saddr, src->reuse, &err)) goto bind_error; g_object_unref (bind_saddr); } else { GST_DEBUG_OBJECT (src, "using provided socket %p", src->socket); /* we use the configured socket, try to get some info about it */ src->used_socket = G_SOCKET (g_object_ref (src->socket)); src->external_socket = TRUE; if (src->addr) g_object_unref (src->addr); src->addr = G_INET_SOCKET_ADDRESS (g_socket_get_local_address (src->used_socket, &err)); if (!src->addr) goto getsockname_error; } #if GLIB_CHECK_VERSION (2, 35, 7) { gint val = 0; if (src->buffer_size != 0) { GError *opt_err = NULL; GST_INFO_OBJECT (src, "setting udp buffer of %d bytes", src->buffer_size); /* set buffer size, Note that on Linux this is typically limited to a * maximum of around 100K. Also a minimum of 128 bytes is required on * Linux. */ if (!g_socket_set_option (src->used_socket, SOL_SOCKET, SO_RCVBUF, src->buffer_size, &opt_err)) { GST_ELEMENT_WARNING (src, RESOURCE, SETTINGS, (NULL), ("Could not create a buffer of requested %d bytes: %s", src->buffer_size, opt_err->message)); g_error_free (opt_err); opt_err = NULL; } } /* read the value of the receive buffer. Note that on linux this returns * 2x the value we set because the kernel allocates extra memory for * metadata. The default on Linux is about 100K (which is about 50K * without metadata) */ if (g_socket_get_option (src->used_socket, SOL_SOCKET, SO_RCVBUF, &val, NULL)) { GST_INFO_OBJECT (src, "have udp buffer of %d bytes", val); } else { GST_DEBUG_OBJECT (src, "could not get udp buffer size"); } } #elif defined (SO_RCVBUF) { gint rcvsize, ret; socklen_t len; len = sizeof (rcvsize); if (src->buffer_size != 0) { rcvsize = src->buffer_size; GST_DEBUG_OBJECT (src, "setting udp buffer of %d bytes", rcvsize); /* set buffer size, Note that on Linux this is typically limited to a * maximum of around 100K. Also a minimum of 128 bytes is required on * Linux. */ ret = setsockopt (g_socket_get_fd (src->used_socket), SOL_SOCKET, SO_RCVBUF, (void *) &rcvsize, len); if (ret != 0) { GST_ELEMENT_WARNING (src, RESOURCE, SETTINGS, (NULL), ("Could not create a buffer of requested %d bytes, %d: %s (%d)", rcvsize, ret, g_strerror (errno), errno)); } } /* read the value of the receive buffer. Note that on linux this returns 2x the * value we set because the kernel allocates extra memory for metadata. * The default on Linux is about 100K (which is about 50K without metadata) */ ret = getsockopt (g_socket_get_fd (src->used_socket), SOL_SOCKET, SO_RCVBUF, (void *) &rcvsize, &len); if (ret == 0) GST_DEBUG_OBJECT (src, "have udp buffer of %d bytes", rcvsize); else GST_DEBUG_OBJECT (src, "could not get udp buffer size"); } #else if (src->buffer_size != 0) { GST_WARNING_OBJECT (src, "don't know how to set udp buffer size on this " "OS. Consider upgrading your GLib to >= 2.35.7 and re-compiling the " "GStreamer udp plugin"); } #endif g_socket_set_broadcast (src->used_socket, TRUE); if (src->auto_multicast && g_inet_address_get_is_multicast (g_inet_socket_address_get_address (src->addr))) { GST_DEBUG_OBJECT (src, "joining multicast group %s", src->host); if (!g_socket_join_multicast_group (src->used_socket, g_inet_socket_address_get_address (src->addr), FALSE, src->multi_iface, &err)) goto membership; } /* NOTE: sockaddr_in.sin_port works for ipv4 and ipv6 because sin_port * follows ss_family on both */ { GInetSocketAddress *addr; guint16 port; addr = G_INET_SOCKET_ADDRESS (g_socket_get_local_address (src->used_socket, &err)); if (!addr) goto getsockname_error; port = g_inet_socket_address_get_port (addr); GST_DEBUG_OBJECT (src, "bound, on port %d", port); if (port != src->port) { src->port = port; GST_DEBUG_OBJECT (src, "notifying port %d", port); g_object_notify (G_OBJECT (src), "port"); } g_object_unref (addr); } return TRUE; /* ERRORS */ name_resolve: { GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL), ("Name resolval failed: %s", err->message)); g_clear_error (&err); g_object_unref (resolver); return FALSE; } no_socket: { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), ("no socket error: %s", err->message)); g_clear_error (&err); g_object_unref (addr); return FALSE; } bind_error: { GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL), ("bind failed: %s", err->message)); g_clear_error (&err); g_object_unref (bind_saddr); gst_udpsrc_stop (GST_BASE_SRC (src)); return FALSE; } membership: { GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL), ("could add membership: %s", err->message)); g_clear_error (&err); gst_udpsrc_stop (GST_BASE_SRC (src)); return FALSE; } getsockname_error: { GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL), ("getsockname failed: %s", err->message)); g_clear_error (&err); gst_udpsrc_stop (GST_BASE_SRC (src)); return FALSE; } }