gint main (void) { gboolean ret; GSocket *socket = NULL; GSocketAddress *address = NULL; GError *error = NULL; gsize wrote; const gchar *buffer = "ping\n"; const gchar *socket_filename = "/tmp/pk-self-test.socket"; GSource *source; GMainLoop *loop; g_type_init (); loop = g_main_loop_new (NULL, FALSE); /* create socket */ socket = g_socket_new (G_SOCKET_FAMILY_UNIX, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT, &error); if (socket == NULL) { g_warning ("failed to create socket: %s", error->message); g_error_free (error); goto out; } g_socket_set_blocking (socket, FALSE); g_socket_set_keepalive (socket, TRUE); /* connect to it */ address = g_unix_socket_address_new (socket_filename); ret = g_socket_connect (socket, address, NULL, &error); if (!ret) { g_warning ("failed to connect to socket: %s", error->message); g_error_free (error); goto out; } /* socket has data */ source = g_socket_create_source (socket, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, NULL); g_source_set_callback (source, (GSourceFunc) pk_socket_example_accept_connection_cb, loop, NULL); g_source_attach (source, NULL); /* send some data */ wrote = g_socket_send (socket, buffer, 5, NULL, &error); if (wrote != 5) { g_warning ("failed to write 5 bytes"); goto out; } /* run main loop */ g_debug ("running main loop"); g_main_loop_run (loop); out: if (loop != NULL) g_main_loop_unref (loop); if (socket != NULL) g_object_unref (socket); if (address != NULL) g_object_unref (address); return 0; }
static void enable_keepalive (GSocketConnection *conn) { /* We enable keepalive on the socket, because data connections can be * idle for a long time while data is transferred using the data * connection. And there are still buggy routers in existance that purge * idle connections from time to time. * To work around this problem, we set the keep alive flag here. It's the * user's responsibility to configure his kernel properly so that the * keepalive packets are sent before the buggy router disconnects the * TCP connection. If a user asks, a howto is at * http://tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO/ */ g_socket_set_keepalive (g_socket_connection_get_socket (conn), TRUE); }
static void _connect_to_host_ready(GObject *source_object, GAsyncResult *res, gpointer user_data) { GSocketClient *socket_client = G_SOCKET_CLIENT(source_object); GSimpleAsyncResult *result = G_SIMPLE_ASYNC_RESULT(user_data); IdleServerConnection *conn = IDLE_SERVER_CONNECTION(g_async_result_get_source_object(G_ASYNC_RESULT(result))); IdleServerConnectionPrivate *priv = IDLE_SERVER_CONNECTION_GET_PRIVATE(conn); GInputStream *input_stream; GSocket *socket_; GSocketConnection *socket_connection; gint nodelay = 1; gint socket_fd; GError *error = NULL; socket_connection = g_socket_client_connect_to_host_finish(socket_client, res, &error); if (socket_connection == NULL) { IDLE_DEBUG("g_socket_client_connect_to_host failed: %s", error->message); g_simple_async_result_set_error(result, TP_ERROR, TP_ERROR_NETWORK_ERROR, "%s", error->message); g_error_free(error); change_state(conn, SERVER_CONNECTION_STATE_NOT_CONNECTED, SERVER_CONNECTION_STATE_REASON_ERROR); g_object_unref(conn); goto cleanup; } socket_ = g_socket_connection_get_socket(socket_connection); g_socket_set_keepalive(socket_, TRUE); socket_fd = g_socket_get_fd(socket_); setsockopt(socket_fd, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof(nodelay)); g_tcp_connection_set_graceful_disconnect(G_TCP_CONNECTION(socket_connection), TRUE); priv->io_stream = G_IO_STREAM(socket_connection); input_stream = g_io_stream_get_input_stream(priv->io_stream); _input_stream_read(conn, input_stream, _input_stream_read_ready); change_state(conn, SERVER_CONNECTION_STATE_CONNECTED, SERVER_CONNECTION_STATE_REASON_REQUESTED); cleanup: g_simple_async_result_complete(result); g_object_unref(result); }
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 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; }