static int remote_connect(const char* host, unsigned port, void** connectiondata) { g_message("connecting to remote: %s on port %u", host, port); GSocket* sock = g_socket_new(G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP, NULL); GSocketConnectable* addr = g_network_address_new(host, port); GSocketAddressEnumerator* enumerator = g_socket_connectable_enumerate(addr); int ret = EMCUETITI_PORT_REMOTE_TRYAGAIN; GSocketAddress* sockaddr; while ((sockaddr = g_socket_address_enumerator_next(enumerator, NULL, NULL))) { g_message("connecting..."); GError* error = NULL; if (g_socket_connect(sock, sockaddr, NULL, &error)) { g_message("connected"); g_socket_set_blocking(sock, FALSE); remote_wireupsocketcallback(sock); *connectiondata = sock; ret = EMCUETITI_PORT_REMOTE_OK; break; } else { g_message("failed to connect %d:%s", error->code, error->message); } } if (ret != EMCUETITI_PORT_REMOTE_OK) g_object_unref(sock); g_object_unref(addr); g_object_unref(enumerator); return ret; }
/* TODO: could use dbus, but for portability maybe not..... */ static void do_connect(SpiceVDAgent *agent) { GError *error = NULL; GSocketAddressEnumerator *enumerator; GSocketAddress *address; #ifdef G_OS_UNIX agent->socket = g_socket_new(G_SOCKET_FAMILY_UNIX, G_SOCKET_TYPE_STREAM, 0, &error); agent->connectable = G_SOCKET_CONNECTABLE(g_unix_socket_address_new(vdagentd_socket)); #endif enumerator = g_socket_connectable_enumerate (agent->connectable); while (TRUE) { address = g_socket_address_enumerator_next (enumerator, agent->cancellable, NULL); if (!address) { g_error("can't connect to socket"); exit(1); } if (g_socket_connect(agent->socket, address, agent->cancellable, &error)) break; g_debug("Connection failed, trying next"); g_clear_error (&error); g_object_unref (address); } g_object_unref(enumerator); agent->connection = G_IO_STREAM(g_socket_connection_factory_create_connection(agent->socket)); g_debug("Connected to %s %p", vdagentd_socket, agent->connection); send_xorg_config(agent); }
gboolean xdmcp_client_start (XDMCPClient *client) { if (client->priv->socket) return TRUE; g_autoptr(GError) error = NULL; client->priv->socket = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, &error); if (error) g_warning ("Error creating XDMCP socket: %s", error->message); if (!client->priv->socket) return FALSE; GSocketConnectable *address = g_network_address_new (client->priv->host, client->priv->port); GSocketAddressEnumerator *enumerator = g_socket_connectable_enumerate (address); while (TRUE) { g_autoptr(GError) e = NULL; g_autoptr(GSocketAddress) socket_address = g_socket_address_enumerator_next (enumerator, NULL, &e); if (e) g_warning ("Failed to get socket address: %s", e->message); if (!socket_address) return FALSE; if (!g_socket_connect (client->priv->socket, socket_address, NULL, &e)) { g_warning ("Unable to connect XDMCP socket: %s", error->message); continue; } g_io_add_watch (g_io_channel_unix_new (g_socket_get_fd (client->priv->socket)), G_IO_IN, xdmcp_data_cb, client); return TRUE; } }
static void next_enumerator (GProxyAddressEnumeratorPrivate *priv) { if (priv->proxy_address) return; while (priv->addr_enum == NULL && *priv->next_proxy) { GSocketConnectable *connectable = NULL; GProxy *proxy; priv->proxy_uri = *priv->next_proxy++; g_free (priv->proxy_type); priv->proxy_type = g_uri_parse_scheme (priv->proxy_uri); if (priv->proxy_type == NULL) continue; /* Assumes hostnames are supported for unknown protocols */ priv->supports_hostname = TRUE; proxy = g_proxy_get_default_for_protocol (priv->proxy_type); if (proxy) { priv->supports_hostname = g_proxy_supports_hostname (proxy); g_object_unref (proxy); } if (strcmp ("direct", priv->proxy_type) == 0) { if (priv->connectable) connectable = g_object_ref (priv->connectable); else connectable = g_network_address_new (priv->dest_hostname, priv->dest_port); } else { GError *error = NULL; connectable = g_network_address_parse_uri (priv->proxy_uri, 0, &error); if (error) { g_warning ("Invalid proxy URI '%s': %s", priv->proxy_uri, error->message); g_error_free (error); } save_userinfo (priv, priv->proxy_uri); } if (connectable) { priv->addr_enum = g_socket_connectable_enumerate (connectable); g_object_unref (connectable); } } }
static void do_connectable (const char *arg, gboolean synchronous) { char **parts; GSocketConnectable *connectable; GSocketAddressEnumerator *enumerator; if (strchr (arg, '/')) { /* service/protocol/domain */ parts = g_strsplit (arg, "/", 3); if (!parts || !parts[2]) usage (); connectable = g_network_service_new (parts[0], parts[1], parts[2]); } else { guint16 port; parts = g_strsplit (arg, ":", 2); if (parts && parts[1]) { arg = parts[0]; port = strtoul (parts[1], NULL, 10); } else port = 0; if (g_hostname_is_ip_address (arg)) { GInetAddress *addr = g_inet_address_new_from_string (arg); GSocketAddress *sockaddr = g_inet_socket_address_new (addr, port); g_object_unref (addr); connectable = G_SOCKET_CONNECTABLE (sockaddr); } else connectable = g_network_address_new (arg, port); } enumerator = g_socket_connectable_enumerate (connectable); g_object_unref (connectable); if (synchronous) do_sync_connectable (enumerator); else do_async_connectable (enumerator); }
/* Tries to resolve priv->name as an IP address, possibly including an * IPv6 scope id. */ static void maybe_resolve_ip (SoupAddress *addr) { SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr); const char *pct, *ip; char *tmp = NULL; GSocketConnectable *gaddr; GSocketAddressEnumerator *sa_enum; GSocketAddress *saddr; if (priv->sockaddr || !priv->name) return; pct = strchr (priv->name, '%'); if (pct) ip = tmp = g_strndup (priv->name, pct - priv->name); else ip = priv->name; if (!g_hostname_is_ip_address (ip)) { g_free (tmp); return; } g_free (tmp); gaddr = g_network_address_new (priv->name, priv->port); if (!gaddr) return; sa_enum = g_socket_connectable_enumerate (gaddr); saddr = g_socket_address_enumerator_next (sa_enum, NULL, NULL); if (saddr) { priv->n_addrs = 1; priv->sockaddr = g_new (struct sockaddr_storage, 1); if (!g_socket_address_to_native (saddr, priv->sockaddr, sizeof (struct sockaddr_storage), NULL)) { /* can't happen: We know the address format is supported * and the buffer is large enough */ g_warn_if_reached (); } g_object_unref (saddr); } g_object_unref (sa_enum); g_object_unref (gaddr); }
/** * cockpit_stream_connect: * @name: name for pipe, for debugging * @address: socket address to connect to * * Create a new pipe connected as a client to the given socket * address, which can be a unix or inet address. Will connect * in stream mode. * * If the connection fails, a pipe is still returned. It will * close once the main loop is run with an appropriate problem. * * Returns: (transfer full): newly allocated CockpitStream. */ CockpitStream * cockpit_stream_connect (const gchar *name, GSocketConnectable *connectable, CockpitStreamOptions *options) { CockpitStream *stream; g_return_val_if_fail (G_IS_SOCKET_CONNECTABLE (connectable), NULL); stream = g_object_new (COCKPIT_TYPE_STREAM, "io-stream", NULL, "name", name, NULL); if (options) stream->priv->options = cockpit_stream_options_ref (options); stream->priv->connecting = g_socket_connectable_enumerate (connectable); g_socket_address_enumerator_next_async (stream->priv->connecting, NULL, on_address_next, g_object_ref (stream)); return stream; }
GSocketAddress * cockpit_channel_parse_address (CockpitChannel *self, gchar **possible_name) { GSocketConnectable *connectable; GSocketAddressEnumerator *enumerator; GSocketAddress *address; GError *error = NULL; gchar *name = NULL; connectable = cockpit_channel_parse_connectable (self, &name); if (!connectable) return NULL; /* This is sync, but realistically, it doesn't matter for current use cases */ enumerator = g_socket_connectable_enumerate (connectable); g_object_unref (connectable); address = g_socket_address_enumerator_next (enumerator, NULL, &error); g_object_unref (enumerator); if (error != NULL) { g_warning ("couldn't find address: %s: %s", name, error->message); cockpit_channel_close (self, "not-found"); g_error_free (error); g_free (name); return NULL; } if (possible_name) *possible_name = name; else g_free (name); return address; }
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; }