static gboolean request_dump (GNetworkMonitorNetlink *nl, GError **error) { struct nlmsghdr *n; struct rtgenmsg *gen; gchar buf[NLMSG_SPACE (sizeof (*gen))]; memset (buf, 0, sizeof (buf)); n = (struct nlmsghdr*) buf; n->nlmsg_len = NLMSG_LENGTH (sizeof (*gen)); n->nlmsg_type = RTM_GETROUTE; n->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP; n->nlmsg_pid = 0; gen = NLMSG_DATA (n); gen->rtgen_family = AF_UNSPEC; if (g_socket_send (nl->priv->sock, buf, sizeof (buf), NULL, error) < 0) { g_prefix_error (error, "%s", _("Could not get network status: ")); return FALSE; } nl->priv->dump_networks = g_ptr_array_new_with_free_func (g_object_unref); return TRUE; }
/* net_write() Writes data (datalen bytes) to the connection Returns number of written bytes, or <=0 if an error is encountered The error is passed to DEBUG_PRINT */ static gint32 net_write (MCACnxn *cnxn, void *data, guint32 datalen) { gint32 retsize; retsize = write_data (cnxn->conn_priv, data, datalen); #if 0 GError *error; assert(cnxn != NULL); #ifdef USE_IO_STREAM assert(cnxn->net_out_stream != NULL); retsize = g_output_stream_write(cnxn->net_out_stream, data, datalen, NULL, &error); #else assert(cnxn->gsocket != NULL); retsize = g_socket_send(cnxn->gsocket, data, datalen, NULL, &error); #endif if (retsize < 0){ DEBUG_PRINT("net_write(): failed: %s\n", error->message); g_error_free(error); } else{ DEBUG_PRINT("net_write(): wrote [%d bytes]\n", retsize); } #endif return retsize; }
gboolean moloch_http_write_cb(gint UNUSED(fd), GIOCondition UNUSED(cond), gpointer data) { MolochConn_t *conn = data; GError *gerror = 0; /*struct timeval startTime; struct timeval endTime; gettimeofday(&startTime, 0); */ if (!conn->request) return FALSE; int sent = g_socket_send(conn->conn, conn->request->data+conn->sent, conn->request->data_len-conn->sent, NULL, &gerror); conn->sent += sent; /*gettimeofday(&endTime, 0); LOG("%s WRITE %d %d %ldms", conn->line, sent, conn->sent, (endTime.tv_sec - startTime.tv_sec)*1000 + (endTime.tv_usec/1000 - startTime.tv_usec/1000));*/ if (gerror) { /* Should free stuff here */ LOG("ERROR: %p: Receive Error: %s", (void*)conn, gerror->message); return FALSE; } gboolean finished = conn->sent == conn->request->data_len; if (finished) moloch_http_finish(conn, FALSE); return !finished; }
gboolean moloch_http_write_cb(gint UNUSED(fd), GIOCondition UNUSED(cond), gpointer data) { MolochConn_t *conn = data; GError *gerror = 0; if (!conn->request) { DEBUGCONN("AAA ww clear %s %p fd:%d,%d ww:%d", conn->server->names[0], conn, fd, g_socket_get_fd(conn->conn), conn->writeWatch); conn->writeWatch = 0; return FALSE; } int sent = g_socket_send(conn->conn, conn->request->data+conn->sent, conn->request->data_len-conn->sent, NULL, &gerror); conn->sent += sent; if (gerror) { /* Should free stuff here */ LOG("ERROR: %p: Write Error: %s", (void*)conn, gerror->message); g_error_free(gerror); DEBUGCONN("AAA ww clear %s %p fd:%d,%d ww:%d", conn->server->names[0], conn, fd, g_socket_get_fd(conn->conn), conn->writeWatch); conn->writeWatch = 0; return FALSE; } gboolean finished = conn->sent == conn->request->data_len; if (finished) { moloch_http_finish(conn, FALSE); DEBUGCONN("AAA ww finish %s %p fd:%d ww:%d", conn->server->names[0], conn, g_socket_get_fd(conn->conn), conn->writeWatch); conn->writeWatch = 0; } return !finished; }
/** * facq_net_send: * @skt: A connected #GSocket object. * @buf: A pointer to the memory area that contains the data that you want to * send. * @size: The size of the memory area pointed by @buf, in bytes. * @retry: The number of retries or 0 for infinite retries. * @err: A #GError, it will be set in case of error if not %NULL. * * Tries to send the number of bytes, @size, in the memory area pointed by @buf, * using at most @retry retries. * * returns: The number of bytes sent if successful, -1 in case of error, * -2 in case of timeout, -3 if wrong parameters are passed to the function. */ gssize facq_net_send(GSocket *skt,gchar *buf,gsize size,guint retry,GError **err) { guint retries = 0; GError *local_err = NULL; gsize to_send = 0, remaining = 0; gssize ret = 0, total = 0; if(!check_values(skt,buf,size)) { if(err != NULL) g_set_error_literal(err,G_IO_ERROR, G_IO_ERROR_FAILED,"Can't send any data"); return -3; } if(retry == 0) retry = G_MAXUINT; to_send = 0; remaining = size; /* Try to send all the data in one call, retrying at most retry times */ for(retries = 0; retries < retry; retries++) { ret = g_socket_send(skt,&buf[to_send],remaining,NULL,&local_err); if(ret <= 0) { if(local_err) { facq_log_write_v(FACQ_LOG_MSG_TYPE_ERROR, "%s",local_err->message); if(err != NULL) g_propagate_error(err,local_err); return -1; } else { if(err != NULL) g_set_error_literal(err,G_IO_ERROR, G_IO_ERROR_FAILED,"Error sending data"); return -1; } } else { total += ret; remaining = size - total; to_send += ret; if(total == size) break; #if ENABLE_DEBUG facq_log_write_v(FACQ_LOG_MSG_TYPE_DEBUG,"%s", "Retrying to send all the data"); #endif } } if(total != size) { if(err != NULL) g_set_error_literal(err,G_IO_ERROR, G_IO_ERROR_TIMED_OUT,"Operation timed out"); return -2; } return total; }
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; }
/* coroutine context */ static void spice_channel_flush_wire(SpiceChannel *channel, const void *data, size_t datalen) { spice_channel *c = channel->priv; const char *ptr = data; size_t offset = 0; GIOCondition cond; while (offset < datalen) { int ret; if (c->has_error) return; cond = 0; if (c->tls) { ret = SSL_write(c->ssl, ptr+offset, datalen-offset); if (ret < 0) { ret = SSL_get_error(c->ssl, ret); if (ret == SSL_ERROR_WANT_READ) cond |= G_IO_IN; if (ret == SSL_ERROR_WANT_WRITE) cond |= G_IO_OUT; ret = -1; } } else { GError *error = NULL; ret = g_socket_send(c->sock, ptr+offset, datalen-offset, NULL, &error); if (ret < 0) { if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) { cond = G_IO_OUT; } else { SPICE_DEBUG("Send error %s", error->message); exit(1); } g_clear_error(&error); ret = -1; } } if (ret == -1) { if (cond != 0) { SPICE_DEBUG("g_io_waiting"); g_io_wait(c->sock, cond); } else { SPICE_DEBUG("Closing the channel: spice_channel_flush %d", errno); c->has_error = TRUE; return; } } if (ret == 0) { SPICE_DEBUG("Closing the connection: spice_channel_flush"); c->has_error = TRUE; return; } offset += ret; } }
static void xdmcp_write (XDMCPClient *client, const guint8 *buffer, gssize buffer_length) { g_autoptr(GError) error = NULL; gssize n_written = g_socket_send (client->priv->socket, (const gchar *) buffer, buffer_length, NULL, &error); if (n_written < 0) g_warning ("Failed to send XDMCP request: %s", error->message); else if (n_written != buffer_length) g_warning ("Partial write for XDMCP request, wrote %zi, expected %zi", n_written, buffer_length); }
void update_client_side_ui_cb(FcitxClient *client, char *auxup, char *auxdown, char *preedit, char *candidateword, char *imname, int cursorpos, void *user_data) { GString *data; GSocket *connection = user_data; data = g_string_new(""); if (!committed->len) g_string_assign(committed, "nil"); if (candidateword[0] == '1') { GRegex *regex; gchar *candidates; regex = g_regex_new(" \\d+\\.", 0, 0, NULL); candidateword += 2; candidateword[strlen(candidateword) - 1] = 0; candidates = g_regex_replace_literal(regex, candidateword, -1, 0, "\" \"", 0, NULL); g_string_printf(data, "'(\"%s\" (\"%s\") %s)", preedit, candidates, committed->str); g_free(candidates); g_free(regex); } else { g_string_printf(data, "'(\"%s\" () %s)", preedit, committed->str); } if (g_socket_send(connection, data->str, data->len, NULL, NULL) == -1) { perror("g_socket_send"); exit(1); } g_string_truncate(committed, 0); g_string_free(data, TRUE); }
gint interface_createAddress(struct node *n) //GInetAddress *addr) { GError * e = NULL; GInetAddress *lo = g_inet_address_new_loopback( G_SOCKET_FAMILY_IPV6); GSocketAddress *sa = g_inet_socket_address_new( lo, 42); GSocket *s = n->ubnetd; if( s != NULL ){ g_socket_close(s,NULL); g_object_unref(s); } s = g_socket_new(G_SOCKET_FAMILY_IPV6, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP, &e); if( e != NULL ){ syslog(LOG_ERR,"interface_pushAddress: Error while creating socket: %s\n", e->message); g_error_free(e); return -1; } g_socket_connect(s, sa, NULL, &e); if( e != NULL ){ syslog(LOG_ERR,"interface_pushAddress: Error while connecting: %s\n", e->message); g_error_free(e); return -1; } g_socket_send(s,"A",1,NULL,NULL); gchar *bytes = (gchar*)g_inet_address_to_bytes(n->netadr); g_socket_send(s,bytes,16,NULL,NULL); n->ubnetd = s; //gchar buf[1]; //g_socket_receive(s,buf,1,NULL,NULL); return 0; }
//Bfoadcast ivy msgs to clients void broadcast_to_clients () { int i; if (uTCP) { //broadcast using tcp connection GError *error = NULL; for (i = 0; i < MAXCLIENT; i++) { if (ConnectedClients[i].used > 0) { GOutputStream * ostream = g_io_stream_get_output_stream (ConnectedClients[i].ClientTcpData); g_output_stream_write(ostream, ivybuffer, strlen(ivybuffer), NULL, &error); } } return; } i=0; for (i = 0; i < MAXCLIENT; i++) { if (ConnectedClients[i].used > 0) { //Send data GInetAddress *udpAddress; GSocketAddress *udpSocketAddress; GSocket *udpSocket; udpAddress = g_inet_address_new_from_string(ConnectedClients[i].client_ip); udpSocketAddress = g_inet_socket_address_new(udpAddress, udp_port); udpSocket = g_socket_new(G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM, 17, NULL); if (g_socket_connect(udpSocket, udpSocketAddress, NULL, NULL) == FALSE) { printf("App Server: stg wrong with socket connect\n"); fflush(stdout); } if (g_socket_send(udpSocket, ivybuffer, strlen(ivybuffer) , NULL, NULL) < 0) { printf("App Server: stg wrong with send func\n"); fflush(stdout); } if (g_socket_close(udpSocket, NULL) == FALSE) { printf("App Server: stg wrong with socket close\n"); fflush(stdout); } //Unref objects g_object_unref(udpAddress); g_object_unref(udpSocketAddress); g_object_unref(udpSocket); } } }
void janus_source_relay_rtp(janus_source_session *session, int video, char *buf, int len) { janus_source_socket * sck = (video ? g_hash_table_lookup(session->sockets, "video_rtp_cli") : g_hash_table_lookup(session->sockets, "audio_rtp_cli")); if (!sck) { JANUS_LOG(LOG_ERR, "Unable to lookup for rtp_cli\n"); return; } if (g_socket_send(sck->socket, buf, len, NULL, NULL) < 0) { //JANUS_LOG(LOG_ERR, "Send RTP failed! type: %s\n", video ? "video" : "audio"); } }
gssize xg_socket_send (GSocket *socket, const gchar *buffer, gsize size) { GError *error; gssize n; n = g_socket_send (socket, buffer, size, NULL, &error); if (n == -1) { g_critical("g_socket_send() returned -1: %s", error->message); } return n; }
/*! \brief wrapper for writing data that handles serial and network modes \param fd is the serial port filedescriptor \param buf is the pointer to where to pull the data from \param count is how many bytes to write \param len is the pointer to length to write \returns TRUE on success, FALSE otherwise */ G_MODULE_EXPORT gboolean write_wrapper(gint fd, const guint8 *buf, size_t count, gint *len) { gint res = 0; GError *error = NULL; Serial_Params *serial_params = NULL; serial_params = (Serial_Params *)DATA_GET(global_data,"serial_params"); ENTER(); log_outbound_data(buf,count); /* printf("write_wrapper\n"); */ if (serial_params->net_mode) { /* printf("net mode write\n"); */ #if GTK_MINOR_VERSION >= 18 res = g_socket_send(serial_params->socket,(const gchar *)buf,(gsize)count,NULL,&error); if (res == -1) { MTXDBG(CRITICAL|SERIAL_WR,_("g_socket_send_error \"%s\"\n\n"),error->message); g_error_free(error); } #else res = send(fd,buf,count,MSG_NOSIGNAL); #endif } else { /* printf("normal write %i bytes\n",count); */ res = write(fd,buf,count); /* printf("result of write is %i\n",res); */ } if (len) *len = res; if (res < 0) { printf(_("Write error! \"%s\"\n"),strerror(errno)); EXIT(); return FALSE; } EXIT(); return TRUE; }
//Bfoadcast ivy msgs to clients void broadcast_to_clients () { int i; for (i = 0; i < MAXCLIENT; i++) { if (ConnectedClients[i].used > 0) { //Send data GInetAddress *udpAddress; GSocketAddress *udpSocketAddress; GSocket *udpSocket; udpAddress = g_inet_address_new_from_string(ConnectedClients[i].client_ip); udpSocketAddress = g_inet_socket_address_new(udpAddress, udp_port); udpSocket = g_socket_new(G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM, 17, NULL); if (g_socket_connect(udpSocket, udpSocketAddress, NULL, NULL) == FALSE) { printf("App Server: stg wrong with socket connect\n"); fflush(stdout); } if (g_socket_send(udpSocket, ivybuffer, strlen(ivybuffer) , NULL, NULL) < 0) { printf("App Server: stg wrong with send func\n"); fflush(stdout); } if (g_socket_close(udpSocket, NULL) == FALSE) { printf("App Server: stg wrong with socket close\n"); fflush(stdout); } //Unref objects g_object_unref(udpAddress); g_object_unref(udpSocketAddress); g_object_unref(udpSocket); } } }
gboolean moloch_http_write_cb(gint UNUSED(fd), GIOCondition UNUSED(cond), gpointer data) { MolochConn_t *conn = data; GError *gerror = 0; if (!conn->request) return FALSE; int sent = g_socket_send(conn->conn, conn->request->data+conn->sent, conn->request->data_len-conn->sent, NULL, &gerror); conn->sent += sent; if (gerror) { /* Should free stuff here */ LOG("ERROR: %p: Receive Error: %s", (void*)conn, gerror->message); g_error_free(gerror); return FALSE; } gboolean finished = conn->sent == conn->request->data_len; if (finished) moloch_http_finish(conn, FALSE); return !finished; }
int main (int argc, char *argv[]) { GSocket *socket, *new_socket, *recv_socket; GSocketAddress *src_address; GSocketAddress *address; GSocketType socket_type; GError *error = NULL; GOptionContext *context; GCancellable *cancellable; g_thread_init (NULL); g_type_init (); context = g_option_context_new (" - Test GSocket server 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 (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; socket = g_socket_new (G_SOCKET_FAMILY_IPV4, socket_type, 0, &error); if (socket == NULL) { g_printerr ("%s: %s\n", argv[0], error->message); return 1; } if (non_blocking) g_socket_set_blocking (socket, FALSE); src_address = g_inet_socket_address_new (g_inet_address_new_any (G_SOCKET_FAMILY_IPV4), port); if (!g_socket_bind (socket, src_address, !dont_reuse_address, &error)) { g_printerr ("Can't bind socket: %s\n", error->message); return 1; } if (!use_udp) { if (!g_socket_listen (socket, &error)) { g_printerr ("Can't listen on socket: %s\n", error->message); return 1; } g_print ("listening on port %d...\n", port); ensure_condition (socket, "accept", cancellable, G_IO_IN); new_socket = g_socket_accept (socket, &error); if (!new_socket) { g_printerr ("Error accepting socket: %s\n", error->message); return 1; } if (non_blocking) g_socket_set_blocking (new_socket, FALSE); address = g_socket_get_remote_address (new_socket, &error); if (!address) { g_printerr ("Error getting remote address: %s\n", error->message); return 1; } g_print ("got a new connection from %s (blocking: %d)\n", socket_address_to_string (address), g_socket_get_blocking (new_socket)); recv_socket = new_socket; } else { recv_socket = socket; new_socket = NULL; } while (TRUE) { gchar buffer[4096] = { }; gssize size; gsize to_send; ensure_condition (recv_socket, "receive", cancellable, G_IO_IN); if (use_udp) size = g_socket_receive_from (recv_socket, &address, buffer, sizeof buffer, &error); else size = g_socket_receive (recv_socket, buffer, sizeof buffer, &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 (address)); g_print ("\n"); if (verbose) g_print ("-------------------------\n" "%.*s\n" "-------------------------\n", (int)size, buffer); to_send = size; while (to_send > 0) { ensure_condition (recv_socket, "send", cancellable, G_IO_OUT); if (use_udp) size = g_socket_send_to (recv_socket, address, buffer, to_send, &error); else size = g_socket_send (recv_socket, buffer, to_send, &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; } } g_print ("connection closed\n"); if (new_socket) { if (!g_socket_close (new_socket, &error)) { g_printerr ("Error closing connection socket: %s\n", error->message); return 1; } g_object_unref (G_OBJECT (new_socket)); } if (!g_socket_close (socket, &error)) { g_printerr ("Error closing master socket: %s\n", error->message); return 1; } g_object_unref (G_OBJECT (socket)); return 0; }
void dasom_send_message (GSocket *socket, DasomMessageType type, gpointer data, guint16 data_len, GDestroyNotify data_destroy_func) { g_debug (G_STRLOC ": %s: fd = %d", G_STRFUNC, g_socket_get_fd (socket)); DasomMessage *message; const DasomMessageHeader *header; GError *error = NULL; gssize n_written; message = dasom_message_new_full (type, data, data_len, data_destroy_func); header = dasom_message_get_header (message); n_written = g_socket_send (socket, (gchar *) header, dasom_message_get_header_size (), NULL, &error); if (G_UNLIKELY (n_written < dasom_message_get_header_size ())) { g_critical (G_STRLOC ": %s: sent %"G_GSSIZE_FORMAT" less than %d", G_STRFUNC, n_written, dasom_message_get_header_size ()); if (error) { g_critical (G_STRLOC ": %s: %s", G_STRFUNC, error->message); g_error_free (error); } dasom_message_unref (message); return; } if (G_LIKELY (message->header->data_len > 0)) { n_written = g_socket_send (socket, message->data, message->header->data_len, NULL, &error); if (G_UNLIKELY (n_written < message->header->data_len)) { g_critical (G_STRLOC ": %s: sent %"G_GSSIZE_FORMAT" less than %d", G_STRFUNC, n_written, message->header->data_len); if (error) { g_critical (G_STRLOC ": %s: %s", G_STRFUNC, error->message); g_error_free (error); } dasom_message_unref (message); return; } } /* debug message */ const gchar *name = dasom_message_get_name (message); if (name) g_debug ("send: %s, fd: %d", name, g_socket_get_fd(socket)); else g_error (G_STRLOC ": unknown message type"); dasom_message_unref (message); }
/*! * Send a QMP message to the hypervisor. * * \param conn \ref clr_oci_vm_conn to use. * \param msg Data to send (json format). * \param msg_len message length. * \param expected_resp_count Expected number of response messages. * \param expect_empty \c true if the response message is expected * to be an empty json message, else \c false. * * \return \c true on success, else \c false. */ static gboolean clr_oci_qmp_msg_send (struct clr_oci_vm_conn *conn, const char *msg, gsize msg_len, gsize expected_resp_count, gboolean expect_empty) { static gboolean initialised = false; const gchar capabilities[] = "{ \"execute\": \"qmp_capabilities\" }"; GError *error = NULL; gssize size; gboolean ret = false; GSList *msgs = NULL; GString *recv_msg = NULL; gsize msg_count = 0; g_assert (conn); g_assert (msg); if (! initialised) { /* The QMP protocol requires we query its capabilities * before sending any further messages. */ g_debug ("sending required initial capabilities " "message (%s)", capabilities); size = g_socket_send (conn->socket, capabilities, sizeof (capabilities)-1, NULL, &error); if (size < 0) { g_critical ("failed to send json: %s", capabilities); if (error) { g_critical ("error: %s", error->message); g_error_free (error); } goto out; } /* Get the response */ ret = clr_oci_qmp_msg_recv (conn->socket, 1, &msgs, &msg_count); if (! ret) { goto out; } recv_msg = g_slist_nth_data (msgs, 0); if (! recv_msg) { ret = false; goto out; } /* Check it */ ret = clr_oci_qmp_check_result (recv_msg->str, recv_msg->len, true); if (! ret) { goto out; } clr_oci_net_msgs_free_all (msgs); initialised = true; /* reset */ recv_msg = NULL; msgs = NULL; msg_count = 0; } g_debug ("sending message '%s'", msg); size = g_socket_send (conn->socket, msg, msg_len, NULL, &error); if (size < 0) { g_critical ("failed to send json: %s", msg); if (error) { g_critical ("error: %s", error->message); g_error_free (error); } goto out; } if (! expected_resp_count) { ret = true; goto out; } /* Get the response */ ret = clr_oci_qmp_msg_recv (conn->socket, expected_resp_count, &msgs, &msg_count); if (! ret) { goto out; } if (expected_resp_count == 1) { /* Expected response: * * - Message 1: return object. */ recv_msg = g_slist_nth_data (msgs, 0); } else if (expected_resp_count == 2) { /* Expected response: * * - Message 1: event object (FIXME: not currently checked). * - Message 2: return object. */ recv_msg = g_slist_nth_data (msgs, 1); } else if (expected_resp_count == 3) { /* Expected response: * * - Message 1: return object. * * - Message 2: timestamp (POWERDOWN event). * * - Message 3: timestamp (SHUTDOWN event). */ recv_msg = g_slist_nth_data (msgs, 0); } else { g_critical ("BUG: don't know how to handle message with %lu responses", (unsigned long int)expected_resp_count); ret = false; goto out; } if (! recv_msg) { ret = false; goto out; } /* Check message */ ret = clr_oci_qmp_check_result (recv_msg->str, recv_msg->len, expect_empty); if (! ret) { goto out; } ret = true; out: if (msgs) { clr_oci_net_msgs_free_all (msgs); } return ret; }
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; }
static gboolean send_request (const gchar *method, const gchar *path, const gchar *content, const gchar *macaroon, gchar **discharges, guint *status_code, gchar **reason_phrase, gchar **response_type, gchar **response, gsize *response_length, GCancellable *cancellable, GError **error) { g_autoptr (GSocket) socket = NULL; g_autoptr (GString) request = NULL; gssize n_written; g_autoptr (GByteArray) buffer = NULL; gsize data_length = 0, header_length; gchar *body = NULL; g_autoptr (SoupMessageHeaders) headers = NULL; gsize chunk_length = 0, n_required; guint8 *chunk_start = NULL; guint code; // NOTE: Would love to use libsoup but it doesn't support unix sockets // https://bugzilla.gnome.org/show_bug.cgi?id=727563 socket = open_snapd_socket (cancellable, error); if (socket == NULL) return FALSE; request = g_string_new (""); g_string_append_printf (request, "%s %s HTTP/1.1\r\n", method, path); g_string_append (request, "Host:\r\n"); if (macaroon != NULL) { gint i; g_string_append_printf (request, "Authorization: Macaroon root=\"%s\"", macaroon); for (i = 0; discharges[i] != NULL; i++) g_string_append_printf (request, ",discharge=\"%s\"", discharges[i]); g_string_append (request, "\r\n"); } if (content) g_string_append_printf (request, "Content-Length: %zu\r\n", strlen (content)); g_string_append (request, "\r\n"); if (content) g_string_append (request, content); g_debug ("begin snapd request: %s", request->str); /* send HTTP request */ n_written = g_socket_send (socket, request->str, request->len, cancellable, error); if (n_written < 0) return FALSE; /* read HTTP headers */ buffer = g_byte_array_new (); while (body == NULL) { if (!read_from_snapd (socket, buffer, &data_length, 1024, cancellable, error)) return FALSE; body = strstr (buffer->data, "\r\n\r\n"); } if (body == NULL) { g_set_error_literal (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_INVALID_FORMAT, "Unable to find header separator in snapd response"); return FALSE; } /* body starts after header divider */ body += 4; header_length = (gsize) ((guint8 *) body - buffer->data); /* parse headers */ headers = soup_message_headers_new (SOUP_MESSAGE_HEADERS_RESPONSE); if (!soup_headers_parse_response (buffer->data, (gint) header_length, headers, NULL, &code, reason_phrase)) { g_set_error_literal (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_INVALID_FORMAT, "snapd response HTTP headers not parseable"); return FALSE; } if (status_code != NULL) *status_code = code; /* read content */ switch (soup_message_headers_get_encoding (headers)) { case SOUP_ENCODING_EOF: while (TRUE) { gsize n_read = data_length; if (!read_from_snapd (socket, buffer, &data_length, 1024, cancellable, error)) return FALSE; if (n_read == data_length) break; chunk_length += data_length - n_read; } break; case SOUP_ENCODING_CHUNKED: // FIXME: support multiple chunks while (TRUE) { chunk_start = strstr (body, "\r\n"); if (chunk_start) break; if (!read_from_snapd (socket, buffer, &data_length, 1024, cancellable, error)) return FALSE; } if (!chunk_start) { g_set_error_literal (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_INVALID_FORMAT, "Unable to find chunk header in " "snapd response"); return FALSE; } chunk_length = strtoul (body, NULL, 16); chunk_start += 2; /* check if enough space to read chunk */ n_required = (chunk_start - buffer->data) + chunk_length; while (data_length < n_required) if (!read_from_snapd (socket, buffer, &data_length, n_required - data_length, cancellable, error)) return FALSE; break; case SOUP_ENCODING_CONTENT_LENGTH: chunk_length = soup_message_headers_get_content_length (headers); chunk_start = body; n_required = header_length + chunk_length; while (data_length < n_required) { if (!read_from_snapd (socket, buffer, &data_length, n_required - data_length, cancellable, error)) return FALSE; } break; default: g_set_error_literal (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_INVALID_FORMAT, "Unable to determine content " "length of snapd response"); return FALSE; } if (response_type) *response_type = g_strdup (soup_message_headers_get_content_type (headers, NULL)); if (response != NULL && chunk_start != NULL) { *response = g_malloc (chunk_length + 2); memcpy (*response, chunk_start, chunk_length + 1); (*response)[chunk_length + 1] = '\0'; g_debug ("snapd status %u: %s", code, *response); } if (response_length) *response_length = chunk_length; return TRUE; }
int main (int argc, char *argv[]) { GSocket *sock = NULL; gchar *addr = NULL; GInetAddress *iaddr = NULL; GSocketAddress *saddr = NULL; gboolean pass = FALSE; guint8 data[4] = { 0, 2, 0 , 0 }; GOptionEntry entries[] = { { "addr", 'a', 0, G_OPTION_ARG_STRING, &addr, "Phone IP address", NULL }, { NULL } }; GOptionContext *context = NULL; GError *error = NULL; g_type_init (); context = g_option_context_new ("- htc nat"); g_option_context_add_main_entries (context, entries, NULL); if (!g_option_context_parse (context, &argc, &argv, &error)) { g_critical ("Option parsing failed: %s", error->message); g_clear_error (&error); goto option_fail; } if (!addr) { gchar *help = g_option_context_get_help (context, TRUE, NULL); g_fprintf (stderr, "%s", help); g_free (help); goto addr_fail; } g_option_context_free (context); sock = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT, &error); if (!sock) { g_critical ("Create socket failed: %s", error->message); g_clear_error (&error); goto sock_fail; } g_socket_set_ttl (sock, 128); iaddr = g_inet_address_new_from_string (addr); saddr = g_inet_socket_address_new (iaddr, 6000); pass = g_socket_connect (sock, saddr, NULL, &error); g_object_unref (iaddr); g_object_unref (saddr); if (!pass) { g_critical ("Connect to server failed: %s", error->message); g_clear_error (&error); goto connect_fail; } pass = g_socket_send (sock, data, 4, NULL, &error); if (!pass) { g_critical ("Send data failed: %s", error->message); g_clear_error (&error); goto send_fail; } g_message ("Sent!"); g_socket_close (sock, NULL); g_object_unref (sock); g_free (addr); return 0; send_fail: connect_fail: g_socket_close (sock, NULL); g_object_unref (sock); sock_fail: g_free (addr); addr_fail: g_option_context_free (context); option_fail: return -1; }
gboolean moloch_http_process_send(MolochConn_t *conn, gboolean sync) { char buffer[3000]; uint32_t len; GError *gerror = 0; MolochRequest_t *request = conn->request; if (conn->conn == 0) { if (moloch_http_connect(conn, moloch_http_get_name(conn->server), conn->server->port, TRUE)) { LOG("%p: Couldn't connect %s", (void*)conn, conn->name); return FALSE; } } len = snprintf(buffer, sizeof(buffer), "%s %.*s HTTP/1.1\r\n" "Host: this.host\r\n" "Content-Type: application/json\r\n" "%s" "Content-Length: %d\r\n" "Connection: keep-alive\r\n" "\r\n", request->method, request->key_len, request->key, request->compress?"Content-Encoding: deflate\r\n":"", (int)request->data_len); gettimeofday(&conn->startTime, NULL); snprintf(conn->line, sizeof(conn->line), "%15.15s %d/%d/%d %p %s %s %.*s %d", ctime(&conn->startTime.tv_sec)+4, conn->server->connQ.e_count, conn->server->requestQ[0].r_count, conn->server->requestQ[1].r_count, (void*)conn, request->method, sync?"SYNC":"ASYNC", request->key_len, request->key, request->data_len); uint32_t sent = 0; while (!gerror && sent < len) { sent += g_socket_send(conn->conn, buffer+sent, len-sent, NULL, &gerror); } /* If async and we have data to send, send it when writable */ if (!sync && request->data_len) { conn->sent = 0; gettimeofday(&conn->sendTime, NULL); moloch_watch_fd(g_socket_get_fd(conn->conn), G_IO_OUT, moloch_http_write_cb, conn); return TRUE; } sent = 0; while (!gerror && sent < request->data_len) { sent += g_socket_send(conn->conn, request->data+sent, request->data_len-sent, NULL, &gerror); } gettimeofday(&conn->sendTime, NULL); if (gerror) { LOG("%p: Send Error: %d %s", (void*)conn, sync, gerror->message); conn->conn = 0; g_error_free(gerror); return FALSE; } moloch_http_finish(conn, sync); return TRUE; }