static VALUE rg_s_parse(G_GNUC_UNUSED VALUE self, VALUE host_and_port, VALUE default_port) { GError *error = NULL; GSocketConnectable *connectable; connectable = g_network_address_parse(RVAL2CSTR(host_and_port), RVAL2GUINT16(default_port), &error); if (connectable == NULL) rbgio_raise_error(error); return GOBJ2RVAL_UNREF(connectable); }
static void on_create_and_connect (GtkButton *button, HotSshTab *self) { HotSshTabPrivate *priv = hotssh_tab_get_instance_private (self); GError *local_error = NULL; GError **error = &local_error; GtkTreeIter iter; gs_unref_object GNetworkAddress *address = NULL; const char *hostname; gs_free char *stripped_hostname = NULL; const char *username; gs_free char *stripped_username = NULL; hostname = gtk_entry_get_text (GTK_ENTRY (priv->host_entry)); stripped_hostname = g_strstrip (g_strdup (hostname)); username = gtk_entry_get_text (GTK_ENTRY (priv->username_entry)); stripped_username = g_strstrip (g_strdup (username)); g_clear_object (&priv->cancellable); priv->cancellable = g_cancellable_new (); g_clear_object (&priv->address); address = (GNetworkAddress*)g_network_address_parse (stripped_hostname, 22, error); if (!address) { page_transition_take_error (self, local_error); return; } g_clear_pointer (&priv->connection_id, g_free); hotssh_hostdb_add_entry (hotssh_hostdb_get_instance (), stripped_username, (GNetworkAddress*)address, &priv->connection_id); hotssh_hostdb_lookup_by_id (hotssh_hostdb_get_instance (), priv->connection_id, &iter); /* gtk_tree_selection_select_iter (gtk_tree_view_get_selection ((GtkTreeView*)priv->connections_treeview), &iter); */ page_transition (self, HOTSSH_TAB_PAGE_LIST_CONNECTIONS); }
static void use_network_address (gboolean synchronous) { GError *error = NULL; GSocketAddressEnumerator *enumerator; GSocketConnectable *connectable; connectable = g_network_address_parse (info, -1, &error); if (error) { print_and_free_error (error); return; } enumerator = g_socket_connectable_proxy_enumerate (connectable); g_object_unref (connectable); printf ("Proxies for hostname and port '%s' are:\n", info); run_with_enumerator (synchronous, enumerator); g_object_unref (enumerator); }
GSocketConnectable * cockpit_channel_parse_connectable (CockpitChannel *self, gchar **possible_name) { const gchar *problem = "protocol-error"; GSocketConnectable *connectable = NULL; const gchar *unix_path; const gchar *internal; JsonObject *options; GError *error = NULL; const gchar *host; gint64 port; options = self->priv->open_options; if (!cockpit_json_get_string (options, "unix", NULL, &unix_path)) { g_warning ("invalid \"unix\" option in channel"); goto out; } if (!cockpit_json_get_int (options, "port", G_MAXINT64, &port)) { g_warning ("invalid \"port\" option in channel"); goto out; } if (!cockpit_json_get_string (options, "internal", NULL, &internal)) { g_warning ("invalid \"internal\" option in channel"); goto out; } if (port != G_MAXINT64 && unix_path) { g_warning ("cannot specify both \"port\" and \"unix\" options"); goto out; } else if (port != G_MAXINT64) { if (port <= 0 || port > 65535) { g_warning ("received invalid \"port\" option"); goto out; } if (cockpit_bridge_local_address) { connectable = g_network_address_parse (cockpit_bridge_local_address, port, &error); host = cockpit_bridge_local_address; } else { connectable = cockpit_loopback_new (port); host = "localhost"; } if (error != NULL) { g_warning ("couldn't parse local address: %s: %s", host, error->message); problem = "internal-error"; goto out; } else { if (possible_name) *possible_name = g_strdup_printf ("%s:%d", host, (gint)port); } } else if (unix_path) { if (possible_name) *possible_name = g_strdup (unix_path); connectable = G_SOCKET_CONNECTABLE (g_unix_socket_address_new (unix_path)); } else if (internal) { gboolean reg = FALSE; if (internal_addresses) { reg = g_hash_table_lookup_extended(internal_addresses, internal, NULL, (gpointer *)&connectable); } if (!connectable) { if (!reg) g_warning ("couldn't find internal address: %s", internal); problem = "not-found"; goto out; } if (possible_name) *possible_name = g_strdup (internal); connectable = g_object_ref (connectable); } else { g_warning ("no \"port\" or \"unix\" or other address option for channel"); goto out; } problem = NULL; out: g_clear_error (&error); if (problem) { cockpit_channel_close (self, problem); if (connectable) g_object_unref (connectable); connectable = NULL; } return connectable; }
int moloch_http_connect(MolochConn_t *conn, char *name, int defaultport, int blocking) { GError *error = 0; GSocketConnectable *connectable; GSocketAddressEnumerator *enumerator; GSocketAddress *sockaddr; if (config.logESRequests) LOG("Connecting %p %s", (void*)conn, name); connectable = g_network_address_parse(name, defaultport, &error); if (error) { LOG("%p: Couldn't parse connect string of %s", (void*)conn, name); exit(0); } conn->name = name; enumerator = g_socket_connectable_enumerate (connectable); g_object_unref(connectable); while (!conn->conn && (sockaddr = g_socket_address_enumerator_next (enumerator, NULL, &error))) { conn->conn = g_socket_new(G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP, &error); if (!error) { GValue value = G_VALUE_INIT; g_value_init (&value, G_TYPE_BOOLEAN); g_value_set_boolean (&value, blocking); g_object_set_property(G_OBJECT(conn->conn), "blocking", &value); g_socket_connect(conn->conn, sockaddr, NULL, &error); } if (error && error->code != G_IO_ERROR_PENDING) { g_object_unref (conn->conn); conn->conn = NULL; } g_object_unref (sockaddr); } g_object_unref (enumerator); if (conn->conn) { if (error) { g_error_free(error); error = 0; } } else if (error) { LOG("%p: Error: %s", (void*)conn, error->message); } if (error || !conn->conn) { conn->server->lastFailedConnect = time(0); return 1; } //g_object_ref (conn->conn); g_socket_set_keepalive(conn->conn, TRUE); int fd = g_socket_get_fd(conn->conn); moloch_watch_fd(fd, MOLOCH_GIO_READ_COND, moloch_http_read_cb, conn); int sendbuff = 0; socklen_t optlen = sizeof(sendbuff); int res = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sendbuff, &optlen); if(res != -1 && sendbuff < 300000) { sendbuff = 300000; setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff)); } #ifdef TCP_KEEPIDLE res = getsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &sendbuff, &optlen); if(res != -1 && sendbuff > 60*8) { sendbuff = 60*8; setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &sendbuff, sizeof(sendbuff)); } #endif return 0; }
int main (int argc, char *argv[]) { GSocket *socket; GSocketAddress *src_address; GSocketAddress *address; GSocketType socket_type; GSocketFamily socket_family; GError *error = NULL; GOptionContext *context; GCancellable *cancellable; GSocketAddressEnumerator *enumerator; GSocketConnectable *connectable; g_thread_init (NULL); g_type_init (); context = g_option_context_new (" <hostname>[:port] - Test GSocket client stuff"); g_option_context_add_main_entries (context, cmd_entries, NULL); if (!g_option_context_parse (context, &argc, &argv, &error)) { g_printerr ("%s: %s\n", argv[0], error->message); return 1; } if (argc != 2) { g_printerr ("%s: %s\n", argv[0], "Need to specify hostname / unix socket name"); return 1; } if (cancel_timeout) { cancellable = g_cancellable_new (); g_thread_create (cancel_thread, cancellable, FALSE, NULL); } else { cancellable = NULL; } loop = g_main_loop_new (NULL, FALSE); if (use_udp) socket_type = G_SOCKET_TYPE_DATAGRAM; else socket_type = G_SOCKET_TYPE_STREAM; if (unix_socket) socket_family = G_SOCKET_FAMILY_UNIX; else socket_family = G_SOCKET_FAMILY_IPV4; socket = g_socket_new (socket_family, socket_type, 0, &error); if (socket == NULL) { g_printerr ("%s: %s\n", argv[0], error->message); return 1; } if (read_timeout) g_socket_set_timeout (socket, read_timeout); if (unix_socket) { GSocketAddress *addr; addr = socket_address_from_string (argv[1]); if (addr == NULL) { g_printerr ("%s: Could not parse '%s' as unix socket name\n", argv[0], argv[1]); return 1; } connectable = G_SOCKET_CONNECTABLE (addr); } else { connectable = g_network_address_parse (argv[1], 7777, &error); if (connectable == NULL) { g_printerr ("%s: %s\n", argv[0], error->message); return 1; } } enumerator = g_socket_connectable_enumerate (connectable); while (TRUE) { address = g_socket_address_enumerator_next (enumerator, cancellable, &error); if (address == NULL) { if (error == NULL) g_printerr ("%s: No more addresses to try\n", argv[0]); else g_printerr ("%s: %s\n", argv[0], error->message); return 1; } if (g_socket_connect (socket, address, cancellable, &error)) break; g_printerr ("%s: Connection to %s failed: %s, trying next\n", argv[0], socket_address_to_string (address), error->message); g_error_free (error); error = NULL; g_object_unref (address); } g_object_unref (enumerator); g_object_unref (connectable); g_print ("Connected to %s\n", socket_address_to_string (address)); /* TODO: Test non-blocking connect */ if (non_blocking) g_socket_set_blocking (socket, FALSE); src_address = g_socket_get_local_address (socket, &error); if (!src_address) { g_printerr ("Error getting local address: %s\n", error->message); return 1; } g_print ("local address: %s\n", socket_address_to_string (src_address)); g_object_unref (src_address); while (TRUE) { gchar buffer[4096]; gssize size; gsize to_send; if (fgets (buffer, sizeof buffer, stdin) == NULL) break; to_send = strlen (buffer); while (to_send > 0) { ensure_condition (socket, "send", cancellable, G_IO_OUT); if (use_udp) size = g_socket_send_to (socket, address, buffer, to_send, cancellable, &error); else size = g_socket_send (socket, buffer, to_send, cancellable, &error); if (size < 0) { if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) { g_print ("socket send would block, handling\n"); g_error_free (error); error = NULL; continue; } else { g_printerr ("Error sending to socket: %s\n", error->message); return 1; } } g_print ("sent %" G_GSSIZE_FORMAT " bytes of data\n", size); if (size == 0) { g_printerr ("Unexpected short write\n"); return 1; } to_send -= size; } ensure_condition (socket, "receive", cancellable, G_IO_IN); if (use_udp) size = g_socket_receive_from (socket, &src_address, buffer, sizeof buffer, cancellable, &error); else size = g_socket_receive (socket, buffer, sizeof buffer, cancellable, &error); if (size < 0) { g_printerr ("Error receiving from socket: %s\n", error->message); return 1; } if (size == 0) break; g_print ("received %" G_GSSIZE_FORMAT " bytes of data", size); if (use_udp) g_print (" from %s", socket_address_to_string (src_address)); g_print ("\n"); if (verbose) g_print ("-------------------------\n" "%.*s" "-------------------------\n", (int)size, buffer); } g_print ("closing socket\n"); if (!g_socket_close (socket, &error)) { g_printerr ("Error closing master socket: %s\n", error->message); return 1; } g_object_unref (G_OBJECT (socket)); g_object_unref (G_OBJECT (address)); return 0; }
int moloch_http_connect(MolochConn_t *conn, char *name, int defaultport, int blocking) { GError *error = 0; GSocketConnectable *connectable; GSocketAddressEnumerator *enumerator; GSocketAddress *sockaddr; struct timeval startTime; struct timeval stopTime; gettimeofday(&startTime, NULL); connectable = g_network_address_parse(name, defaultport, &error); if (error) { LOG("%p: Couldn't parse connect string of %s", (void*)conn, name); exit(0); } conn->name = name; enumerator = g_socket_connectable_enumerate (connectable); g_object_unref(connectable); while (!conn->conn && (sockaddr = g_socket_address_enumerator_next (enumerator, NULL, &error))) { conn->conn = g_socket_new(G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP, &error); if (!error) { GValue value = G_VALUE_INIT; g_value_init (&value, G_TYPE_BOOLEAN); g_value_set_boolean (&value, blocking); g_object_set_property(G_OBJECT(conn->conn), "blocking", &value); g_socket_connect(conn->conn, sockaddr, NULL, &error); } if (error && error->code != G_IO_ERROR_PENDING) { g_object_unref (conn->conn); conn->conn = NULL; } else { struct sockaddr_in localAddress, remoteAddress; socklen_t addressLength = sizeof(localAddress); getsockname(g_socket_get_fd(conn->conn), (struct sockaddr*)&localAddress, &addressLength); g_socket_address_to_native(sockaddr, &remoteAddress, addressLength, NULL); char sessionId[MOLOCH_SESSIONID_LEN]; moloch_session_id(sessionId, localAddress.sin_addr.s_addr, localAddress.sin_port, remoteAddress.sin_addr.s_addr, remoteAddress.sin_port); DEBUGCONN("AAA connected %s %p %s", conn->server->names[0], conn, moloch_friendly_session_id(17, localAddress.sin_addr.s_addr, htons(localAddress.sin_port), remoteAddress.sin_addr.s_addr, htons(remoteAddress.sin_port))); HASH_ADD(h_, connections, sessionId, conn); memcpy(&conn->sessionIda, sessionId, 8); memcpy(&conn->sessionIdb, sessionId+8, 4); conn->server->numConns++; } g_object_unref (sockaddr); } g_object_unref (enumerator); if (conn->conn) { if (error) { g_error_free(error); error = 0; } } else if (error) { LOG("%p: Error: %s", (void*)conn, error->message); } if (error || !conn->conn) { if (config.logESRequests) LOG("Connecting %p %s %d %d FAIL", (void*)conn, name, defaultport, blocking); conn->server->lastFailedConnect = time(0); return 1; } //g_object_ref (conn->conn); g_socket_set_keepalive(conn->conn, TRUE); int fd = g_socket_get_fd(conn->conn); conn->readWatch = moloch_watch_fd(fd, MOLOCH_GIO_READ_COND, moloch_http_read_cb, conn); if (!blocking) { conn->writeWatch = moloch_watch_fd(fd, G_IO_OUT, moloch_http_conn_cb, conn); DEBUGCONN("AAA connwritewatch %s %p fd:%d ww:%d", conn->server->names[0], conn, fd, conn->writeWatch); } int sendbuff = 0; socklen_t optlen = sizeof(sendbuff); int res = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sendbuff, &optlen); if(res != -1 && sendbuff < 300000) { sendbuff = 300000; setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff)); } #ifdef TCP_KEEPIDLE res = getsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &sendbuff, &optlen); if(res != -1 && sendbuff > 60*8) { sendbuff = 60*8; setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &sendbuff, sizeof(sendbuff)); } #endif gettimeofday(&stopTime, NULL); if (config.logESRequests) LOG("Connecting %p %s %d %d %ldms", (void*)conn, name, defaultport, blocking, (stopTime.tv_sec - startTime.tv_sec)*1000 + (stopTime.tv_usec - startTime.tv_usec)/1000); return 0; }
static gboolean make_connection (const char *argument, GTlsCertificate *certificate, GCancellable *cancellable, GSocket **socket, GSocketAddress **address, GIOStream **connection, GInputStream **istream, GOutputStream **ostream, GError **error) { GSocketType socket_type; GSocketFamily socket_family; GSocketAddressEnumerator *enumerator; GSocketConnectable *connectable; GSocketAddress *src_address; GTlsInteraction *interaction; GError *err = NULL; if (use_udp) socket_type = G_SOCKET_TYPE_DATAGRAM; else socket_type = G_SOCKET_TYPE_STREAM; if (unix_socket) socket_family = G_SOCKET_FAMILY_UNIX; else socket_family = G_SOCKET_FAMILY_IPV4; *socket = g_socket_new (socket_family, socket_type, 0, error); if (*socket == NULL) return FALSE; if (read_timeout) g_socket_set_timeout (*socket, read_timeout); if (unix_socket) { GSocketAddress *addr; addr = socket_address_from_string (argument); if (addr == NULL) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Could not parse '%s' as unix socket name", argument); return FALSE; } connectable = G_SOCKET_CONNECTABLE (addr); } else { connectable = g_network_address_parse (argument, 7777, error); if (connectable == NULL) return FALSE; } enumerator = g_socket_connectable_enumerate (connectable); while (TRUE) { *address = g_socket_address_enumerator_next (enumerator, cancellable, error); if (*address == NULL) { if (error != NULL && *error == NULL) g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "No more addresses to try"); return FALSE; } if (g_socket_connect (*socket, *address, cancellable, &err)) break; g_message ("Connection to %s failed: %s, trying next", socket_address_to_string (*address), err->message); g_clear_error (&err); g_object_unref (*address); } g_object_unref (enumerator); g_print ("Connected to %s\n", socket_address_to_string (*address)); src_address = g_socket_get_local_address (*socket, error); if (!src_address) { g_prefix_error (error, "Error getting local address: "); return FALSE; } g_print ("local address: %s\n", socket_address_to_string (src_address)); g_object_unref (src_address); if (use_udp) { *connection = NULL; *istream = NULL; *ostream = NULL; } else *connection = G_IO_STREAM (g_socket_connection_factory_create_connection (*socket)); if (tls) { GIOStream *tls_conn; tls_conn = g_tls_client_connection_new (*connection, connectable, error); if (!tls_conn) { g_prefix_error (error, "Could not create TLS connection: "); return FALSE; } g_signal_connect (tls_conn, "accept-certificate", G_CALLBACK (accept_certificate), NULL); interaction = g_tls_console_interaction_new (); g_tls_connection_set_interaction (G_TLS_CONNECTION (tls_conn), interaction); g_object_unref (interaction); if (certificate) g_tls_connection_set_certificate (G_TLS_CONNECTION (tls_conn), certificate); g_object_unref (*connection); *connection = G_IO_STREAM (tls_conn); if (!g_tls_connection_handshake (G_TLS_CONNECTION (tls_conn), cancellable, error)) { g_prefix_error (error, "Error during TLS handshake: "); return FALSE; } } g_object_unref (connectable); if (*connection) { *istream = g_io_stream_get_input_stream (*connection); *ostream = g_io_stream_get_output_stream (*connection); } return TRUE; }
static GSocketConnectable * parse_address (CockpitChannel *self, gchar **possible_name, gboolean *local_address) { GSocketConnectable *connectable = NULL; const gchar *unix_path; const gchar *internal; const gchar *address; JsonObject *options; gboolean local = FALSE; GError *error = NULL; const gchar *host; gint64 port; gchar *name = NULL; gboolean open = FALSE; options = self->priv->open_options; if (!cockpit_json_get_string (options, "unix", NULL, &unix_path)) { cockpit_channel_fail (self, "protocol-error", "invalid \"unix\" option in channel"); goto out; } if (!cockpit_json_get_int (options, "port", G_MAXINT64, &port)) { cockpit_channel_fail (self, "protocol-error", "invalid \"port\" option in channel"); goto out; } if (!cockpit_json_get_string (options, "internal", NULL, &internal)) { cockpit_channel_fail (self, "protocol-error", "invalid \"internal\" option in channel"); goto out; } if (!cockpit_json_get_string (options, "address", NULL, &address)) { cockpit_channel_fail (self, "protocol-error", "invalid \"address\" option in channel"); goto out; } if (port != G_MAXINT64 && unix_path) { cockpit_channel_fail (self, "protocol-error", "cannot specify both \"port\" and \"unix\" options"); goto out; } else if (port != G_MAXINT64) { if (port <= 0 || port > 65535) { cockpit_channel_fail (self, "protocol-error", "received invalid \"port\" option"); goto out; } if (address) { connectable = g_network_address_new (address, port); host = address; /* This isn't perfect, but matches the use case. Specify address => non-local */ local = FALSE; } else if (cockpit_bridge_local_address) { connectable = g_network_address_parse (cockpit_bridge_local_address, port, &error); host = cockpit_bridge_local_address; local = TRUE; } else { connectable = cockpit_loopback_new (port); host = "localhost"; local = TRUE; } if (error != NULL) { cockpit_channel_fail (self, "internal-error", "couldn't parse local address: %s: %s", host, error->message); goto out; } else { name = g_strdup_printf ("%s:%d", host, (gint)port); } } else if (unix_path) { name = g_strdup (unix_path); connectable = G_SOCKET_CONNECTABLE (g_unix_socket_address_new (unix_path)); local = FALSE; } else if (internal) { gboolean reg = lookup_internal (internal, &connectable); if (!connectable) { if (reg) cockpit_channel_close (self, "not-found"); else cockpit_channel_fail (self, "not-found", "couldn't find internal address: %s", internal); goto out; } name = g_strdup (internal); connectable = g_object_ref (connectable); local = FALSE; } else { cockpit_channel_fail (self, "protocol-error", "no \"port\" or \"unix\" or other address option for channel"); goto out; } open = TRUE; out: g_clear_error (&error); if (open) { if (possible_name) *possible_name = g_strdup (name); if (local_address) *local_address = local; } else { if (connectable) g_object_unref (connectable); connectable = NULL; } g_free (name); return connectable; }