static void on_throttle_pressure (GObject *object, gboolean throttle, gpointer user_data) { CockpitChannel *self = COCKPIT_CHANNEL (user_data); GQueue *throttled; JsonObject *ping; if (throttle) { if (!self->priv->throttled) self->priv->throttled = g_queue_new (); } else { throttled = self->priv->throttled; self->priv->throttled = NULL; while (throttled) { ping = g_queue_pop_head (throttled); if (!ping) { g_queue_free (throttled); throttled = NULL; } else { if (!process_ping (self, ping)) g_assert_not_reached (); /* Because throttle is FALSE */ json_object_unref (ping); } } } }
static void * process_command_thread(void * other) { struct fuse_client * c = other; int ret=0; char tosend[sizeof(struct afp_server_response) + MAX_CLIENT_RESPONSE]; struct afp_server_response response; switch(c->incoming_string[0]) { case AFP_SERVER_COMMAND_MOUNT: ret=process_mount(c); break; case AFP_SERVER_COMMAND_STATUS: ret=process_status(c); break; case AFP_SERVER_COMMAND_UNMOUNT: ret=process_unmount(c); break; case AFP_SERVER_COMMAND_SUSPEND: ret=process_suspend(c); break; case AFP_SERVER_COMMAND_RESUME: ret=process_resume(c); break; case AFP_SERVER_COMMAND_PING: ret=process_ping(c); break; case AFP_SERVER_COMMAND_EXIT: ret=process_exit(c); break; default: log_for_client((void *)c,AFPFSD,LOG_ERR,"Unknown command\n"); } /* Send response */ response.result=ret; response.len=strlen(c->client_string); bcopy(&response,tosend,sizeof(response)); bcopy(c->client_string,tosend+sizeof(response),response.len); ret=write(c->fd,tosend,sizeof(response)+response.len); if (ret<0) { perror("Writing"); } if ((!c) || (c->fd==0)) return NULL; rm_fd_and_signal(c->fd); close(c->fd); remove_client(c); return NULL; }
/****************************************************************************** * * * Function: do_ping * * * * Purpose: ping hosts listed in the host files * * * * Parameters: * * * * Return value: SUCCEED - successfully processed hosts * * NOTSUPPORTED - otherwise * * * * Author: Alexei Vladishev * * * * Comments: use external binary 'fping' to avoid superuser privileges * * * ******************************************************************************/ int do_ping(ZBX_FPING_HOST *hosts, int hosts_count, int count, int interval, int size, int timeout, char *error, int max_error_len) { const char *__function_name = "do_ping"; int res; zabbix_log(LOG_LEVEL_DEBUG, "In %s() hosts_count:%d", __function_name, hosts_count); if (NOTSUPPORTED == (res = process_ping(hosts, hosts_count, count, interval, size, timeout, error, max_error_len))) zabbix_log(LOG_LEVEL_ERR, "%s", error); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(res)); return res; }
/****************************************************************************** * * * Function: do_ping * * * * Purpose: ping hosts listed in the host files * * * * Parameters: * * * * Return value: => 0 - successfully processed items * * FAIL - otherwise * * * * Author: Alexei Vladishev * * * * Comments: use external binary 'fping' to avoid superuser priviledges * * * ******************************************************************************/ int do_ping(ZBX_FPING_HOST *hosts, int hosts_count, char *error, int max_error_len) { int res; zabbix_log(LOG_LEVEL_DEBUG, "In do_ping(hosts_count:%d)", hosts_count); if (NOTSUPPORTED == (res = process_ping(hosts, hosts_count, error, max_error_len))) { zabbix_log(LOG_LEVEL_ERR, "%s", error); zabbix_syslog("%s", error); } zabbix_log(LOG_LEVEL_DEBUG, "End of do_ping():%s", zbx_result_string(res)); return res; }
static void process_control (CockpitChannel *self, const gchar *command, JsonObject *options) { CockpitChannelClass *klass; const gchar *problem; if (g_str_equal (command, "close")) { g_debug ("close channel %s", self->priv->id); if (!cockpit_json_get_string (options, "problem", NULL, &problem)) problem = NULL; cockpit_channel_close (self, problem); return; } if (g_str_equal (command, "ping")) { process_ping (self, options); return; } else if (g_str_equal (command, "pong")) { process_pong (self, options); return; } else if (g_str_equal (command, "done")) { if (self->priv->received_done) cockpit_channel_fail (self, "protocol-error", "channel received second done"); else self->priv->received_done = TRUE; } klass = COCKPIT_CHANNEL_GET_CLASS (self); if (klass->control) (klass->control) (self, command, options); }
int main(int argc, const char * argv[]) { #ifdef ICMP // get the ping socket int ping = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP); { // Drop privelege immediately errno_t ping_errno = errno; setuid(getuid()); if (0 > ping) { errno = ping_errno; DIE(EX_OSERR, "open ping socket"); } LOG(2, "ping socket: %d", ping); } #endif // ICMP #ifdef DNS // get the dns socket int dns = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); { if (0 > dns) { DIE(EX_OSERR, "open dns socket"); } LOG(2, "dns socket: %d", dns); } #endif // DNS struct pollfd fds[2] = { #ifdef ICMP { ping, POLLIN, 0 } #endif // ICMP #ifdef BOTH , #endif // BOTH #ifdef DNS { dns, POLLIN, 0 } #endif // DNS }; int fd_count = 0; #ifdef ICMP int ping_index = fd_count++; #endif // ICMP #ifdef DNS int dns_index = fd_count++; #endif // DNS // process arguments struct opts_t opts; get_opts(argc, argv, &opts); const struct addrinfo * addr = get_one_host(opts.target); #ifdef ICMP int sequence = -1; struct icmp icmp_template; construct_icmp_template(&icmp_template); #endif // ICMP #ifdef DNS void * dns_template; size_t template_size = construct_dns_template(&dns_template, opts.query); LOG(3, "template: "); if (verbose() >= 3) { fputbuf(stderr, dns_template, template_size);fputc('\n', stderr); } #endif // DNS // initialize the prng srandomdev(); int count = -1; while (1) { ++count; #ifdef ICMP struct icmp icmp_message; size_t icmp_message_size; icmp_message_size = construct_icmp(&icmp_template, &icmp_message, ++sequence); ssize_t icmp_sent = sendto(ping, (const void *)&icmp_message, icmp_message_size, 0, addr->ai_addr, addr->ai_addrlen); if (0 > icmp_sent) DIE(EX_OSERR, "sendto ping"); LOG(1, "ping sent %d bytes", icmp_sent); long icmp_send_time = now_us(); long icmp_recv_time = -1; #endif // ICMP #ifdef DNS void * dns_message; size_t dns_message_size; short dns_id = (short)random(); dns_message_size = construct_dns(dns_template, template_size, &dns_message, dns_id); ssize_t dns_sent = sendto(dns, (const void *)dns_message, dns_message_size, 0, addr->ai_addr, addr->ai_addrlen); LOG(1, "dns sent %d bytes", dns_sent); if (verbose() >= 3) { fputbuf(stderr, dns_message, dns_message_size);fputc('\n', stderr); } if (0 > dns_sent) DIE(EX_OSERR, "sendto dns"); long dns_send_time = now_us(); long dns_recv_time = -1; #endif // DNS long ttd_ms = now_ms() + opts.period_ms; int poll_time = (int)opts.period_ms; int ret; while ((ret = poll(fds, fd_count, poll_time))) { if (0 > ret) DIE(EX_OSERR, "poll"); #ifdef ICMP if (fds[ping_index].revents & POLLERR) { int error = 0; socklen_t errlen = sizeof(error); if (0 < getsockopt(fds[0].fd, SOL_SOCKET, SO_ERROR, (void *)&error, &errlen)) DIE(EX_OSERR, "getsockopt on ping while handling POLLERR"); errno = error; DIE(EX_OSERR, "POLLERR on ping"); } if (fds[ping_index].revents & POLLIN) { icmp_recv_time = process_ping(fds[ping_index].fd, sequence); } #endif // ICMP #ifdef DNS if (fds[dns_index].revents & POLLERR) { int error = 0; socklen_t errlen = sizeof(error); if (0 < getsockopt(fds[1].fd, SOL_SOCKET, SO_ERROR, (void *)&error, &errlen)) DIE(EX_OSERR, "getsockopt on dns while handling POLLERR"); errno = error; DIE(EX_OSERR, "POLLERR on dns"); } if (fds[dns_index].revents & POLLIN) { dns_recv_time = process_dns(fds[dns_index].fd, dns_id); } #endif // DNS poll_time = (int)(ttd_ms - now_ms()); if (poll_time < 0) break; } LOG(1, "poll period %d ended", count); #ifdef ICMP REPORT("icmp", icmp_send_time, icmp_recv_time, sequence); #endif // ICMP #ifdef DNS REPORT("dns", dns_send_time, dns_recv_time, dns_id); #endif // DNS } return 0; }
static void dispatch_inbound_command (CockpitWebService *self, CockpitSocket *socket, GBytes *payload) { const gchar *problem = "protocol-error"; const gchar *command; const gchar *channel; JsonObject *options = NULL; gboolean valid = FALSE; valid = cockpit_transport_parse_command (payload, &command, &channel, &options); if (!valid) goto out; if (g_strcmp0 (command, "init") == 0) { problem = process_socket_init (self, socket, options); valid = (problem == NULL); goto out; } if (!socket->init_received) { g_message ("web socket did not send 'init' message first"); valid = FALSE; goto out; } valid = TRUE; if (g_strcmp0 (command, "open") == 0) { valid = process_and_relay_open (self, socket, channel, options); } else if (g_strcmp0 (command, "authorize") == 0) { valid = process_socket_authorize (self, socket, channel, options, payload); } else if (g_strcmp0 (command, "logout") == 0) { valid = process_logout (self, options); if (valid) { /* logout is broadcast to everyone */ if (!self->sent_done) cockpit_transport_send (self->transport, NULL, payload); } } else if (g_strcmp0 (command, "close") == 0) { if (channel == NULL) { g_warning ("got close command without a channel"); valid = FALSE; } else { valid = process_and_relay_close (self, socket, channel, payload); } } else if (g_strcmp0 (command, "kill") == 0) { valid = process_kill (self, socket, options, payload); } else if (!channel && g_strcmp0 (command, "ping") == 0) { valid = process_ping (self, socket, options); } else if (channel) { /* Relay anything with a channel by default */ if (!self->sent_done) cockpit_transport_send (self->transport, NULL, payload); } out: if (!valid) inbound_protocol_error (self, socket->connection, problem); if (options) json_object_unref (options); }