123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379 |
- /* tsiproxy server commands */
- #include <stdlib.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <string.h>
- #include <arpa/inet.h>
- #include <netinet/in.h>
- #include <sys/utsname.h>
- #include <sys/resource.h>
- #include <sys/types.h>
- #include <sys/stat.h>
-
- #include <errno.h>
- #include <dirent.h>
- #include <fcntl.h>
-
- #include "libfuncs/libfuncs.h"
-
- #include "data.h"
- #include "conf.h"
-
- extern CONFIG *config;
- extern char *server_ver;
- extern LIST *netconf, *clients, *chanconf, *restreamer;
- extern STATS allstats;
-
- static void std_headers(int clientsock, char *IP) {
- fdputsf(clientsock, "X-IP: %s\n", IP);
- send_header_textplain(clientsock);
- fdputs(clientsock, "\n");
- }
-
- void run_ping(unsigned int clientsock, acl_t acl, uint32_t src_ip, char *IP) {
- unused(src_ip);
- char flags[6] = "-----";
- send_200_ok(clientsock);
- if (acl.stats ) flags[1] = 'S';
- if (acl.reconf) flags[2] = 'F';
- if (acl.access) flags[3] = 'A';
- fdputsf(clientsock, "X-Access: %s\n", flags);
- std_headers(clientsock, IP);
- fdputs(clientsock, "PONG\n");
- }
-
- int __show_stats(unsigned int clientsock, acl_t acl, char *IP) {
- if (!acl.stats) {
- LOGf("DENY : Stats access denied | IP: %s\n", IP);
- send_403_forbidden(clientsock);
- return 0;
- }
- send_200_ok(clientsock);
- std_headers(clientsock, IP);
- return 1;
- }
-
- void show_stats(unsigned int clientsock, acl_t acl, char *IP) {
- if (!__show_stats(clientsock, acl, IP))
- return;
- time_t now = time(NULL);
- LNODE *l, *tmp;
- list_lock(clients);
- list_for_each_reverse(clients, l, tmp) {
- CLIENT *c = l->data;
- // Workaround for unknown bug that leaves records in clients list but not in restreamerX->clients list
- // Such a client hangs forever taking memory. The bug was seen on snaps server
- if (now - c->ts >= NO_TRAFFIC_SECONDS + 5) {
- list_unlock(clients);
- stop_client_shutdown(c);
- list_lock(clients);
- continue;
- }
- if (c->traffic_out == 0)
- continue;
- // IP A FD PROV CID TRA TM CHAN AGENT
- fdputsf(clientsock,"%s\t%c\t%i\t%-12s\t%lu\t%14llu\t%6lu\t%-22s\t%s\n",
- c->IP,
- '-',
- c->fno,
- "-",
- c->clientid,
- c->traffic_out,
- now - c->start,
- c->chan,
- c->agent);
- }
- list_unlock(clients);
- }
-
- int __show_info(unsigned int clientsock, acl_t acl, char *IP,
- unsigned long total_clients,
- unsigned long clients_current, unsigned long clients_gone,
- unsigned long long traffic_in, unsigned long long traffic_out)
- {
- int used_fds = -1;
- if (!acl.stats) {
- LOGf("DENY : Info access denied | IP: %s\n", IP);
- send_403_forbidden(clientsock);
- return 0;
- }
- time_t now = time(NULL);
- time_t uptime = now - allstats.start_ts;
- unsigned int t_sec,t_min,t_hour,t_days;
- struct rlimit limit;
- double load_avg[3];
-
- t_sec = uptime % 60;
- t_min = (uptime - t_sec) / 60;
- t_hour = (t_min - t_min % 60) / 60;
- t_min = t_min - t_hour * 60;
- t_days = (t_hour - t_hour % 24) / 24;
- t_hour = t_hour - t_days * 24;
-
- getrlimit(RLIMIT_NOFILE, &limit);
- getloadavg(load_avg, 3);
-
- send_200_ok(clientsock);
- std_headers(clientsock, IP);
- fdputs (clientsock, "Server info\n");
- fdputsf(clientsock, " Ident : %s\n", config->ident);
- fdputsf(clientsock, " Version : %s\n", server_ver);
- fdputsf(clientsock, " Server : %s %s %s %s %s\n",
- allstats.utsdata.sysname,
- allstats.utsdata.nodename,
- allstats.utsdata.release,
- allstats.utsdata.version,
- allstats.utsdata.machine);
- fdputsf(clientsock, " Cores : %ld\n", (long)sysconf(_SC_NPROCESSORS_ONLN));
-
- DIR *d = opendir("/proc/self/fd");
- if (d) {
- struct dirent *dir;
- while ((dir = readdir(d))) {
- if (dir->d_name[0] == '.') // Ignore . and ..
- continue;
- used_fds++;
- }
- closedir(d);
- }
- fdputsf(clientsock, " Max FDs : %ld\n",(long)limit.rlim_max);
- fdputsf(clientsock, " Used FDs : %ld\n",(long)used_fds);
- fdputsf(clientsock, " Load average : %4.2f %4.2f %4.2f\n",load_avg[0],load_avg[1],load_avg[2]);
- fdputsf(clientsock, " Localtime : %s", ctime(&now));
- fdputsf(clientsock, " Uptime : %d %02d:%02d:%02d\n", t_days, t_hour, t_min, t_sec);
- fdputsf(clientsock, " Redirect : %s %s\n\n",
- config->redirect_url ? "enabled" : "disabled",
- config->redirect_url ? config->redirect_url : ""
- );
-
- fdputs (clientsock, "Statistics\n");
- fdputsf(clientsock, " Clients current : %lu\n", clients_current);
- fdputsf(clientsock, " Clients cur+gone : %lu\n", clients_current + clients_gone);
- fdputsf(clientsock, " Traffic in : %llu MB\n", traffic_in / (1024*1024));
- fdputsf(clientsock, " Traffic out : %llu MB\n", traffic_out / (1024*1024));
- fdputsf(clientsock, " Total clients : %lu\n\n", total_clients);
-
- return 1;
- }
-
- void show_info(unsigned int clientsock, acl_t acl, char *IP) {
- if (!__show_info(clientsock, acl, IP, allstats.clients, allstats.clients_current, allstats.clients_gone, allstats.traffic_in, allstats.traffic_out))
- return;
-
- time_t now = time(NULL);
- time_t uptime = now - allstats.start_ts;
- fdputs (clientsock, "IPTVD statistics\n");
- fdputsf(clientsock, " Proxies current : %u\n", restreamer->items);
- fdputsf(clientsock, " Restreamers : %lu\n", allstats.child_servers);
- fdputsf(clientsock, " Connects : %lu\n", allstats.clients_all);
- fdputsf(clientsock, " Errors : %lu\n", allstats.errors);
- fdputs (clientsock, " current cur+gone trafic_in traffic_out clients servers connects errors localtime uptime\n");
- fdputsf(clientsock, "AllStats : %lu %lu %llu %llu %lu %lu %lu %lu %lu %lu\n\n",
- allstats.clients_current,
- allstats.clients_current + allstats.clients_gone,
- allstats.traffic_in,
- allstats.traffic_out,
- allstats.clients,
- allstats.child_servers,
- allstats.clients_all,
- allstats.errors,
- now,
- uptime);
-
- LNODE *l, *tmp;
- unsigned int t_sec,t_min,t_hour,t_days;
- fdputs(clientsock, "Running restreamers\n");
- list_lock(restreamer);
- list_for_each_reverse(restreamer, l, tmp) {
- RESTREAMER *r = l->data;
- uptime = time(NULL) - r->started;
-
- t_sec = uptime % 60;
- t_min = (uptime - t_sec) / 60;
- t_hour = (t_min - t_min % 60) / 60;
- t_min = t_min - t_hour * 60;
- t_days = (t_hour - t_hour % 24) / 24;
- t_hour = t_hour - t_days * 24;
-
- fdputsf(clientsock," %-27sClients: %i Served: %li Conn: %li Uptime: %d %02d:%02d:%02d In: %lli %lli MB Out: %lli %lli MB\n",
- r->name,
- r->clients->items,
- r->served,
- r->connects,
- t_days, t_hour, t_min, t_sec,
- r->traffic_in, r->traffic_in / (1024*1024),
- r->traffic_out, r->traffic_out / (1024*1024)
- );
- }
- list_unlock(restreamer);
- fdputs(clientsock,"\n");
- }
-
- void run_livecheck(unsigned int clientsock, acl_t acl, char *IP) {
- if (!acl.reconf) {
- LOGf("DENY : LiveCheck access denied | IP: %s\n", IP);
- send_403_forbidden(clientsock);
- return;
- }
- send_200_ok(clientsock);
- std_headers(clientsock, IP);
- do {
- char outbuf[128];
- int size;
- memset(outbuf, ' ', sizeof(outbuf));
- outbuf[sizeof(outbuf)-1] = '\n';
- STATS ls = allstats;
- sleep(1);
- time_t now = time(NULL);
- time_t uptime = now - allstats.start_ts;
- /* The traffic passed in the 1 second sleep above */
- ls.traffic_in = allstats.traffic_in - ls.traffic_in;
- ls.traffic_out = allstats.traffic_out - ls.traffic_out;
- size = sprintf(outbuf, "%lu %lu %lu %u %llu %llu",
- now,
- uptime,
- allstats.clients_current,
- restreamer ? restreamer->items : 0,
- ls.traffic_in,
- ls.traffic_out);
- outbuf[size]=' ';
- if (fdwrite(clientsock, outbuf, sizeof(outbuf)) <= 0)
- break;
- } while (1);
- }
-
- void read_info(unsigned int clientsock, acl_t acl, char *IP) {
- if (!acl.stats) {
- LOGf("DENY : Info access denied | IP: %s\n", IP);
- send_403_forbidden(clientsock);
- return;
- }
- time_t now = time(NULL);
- time_t uptime = now - allstats.start_ts;
- send_200_ok(clientsock);
- std_headers(clientsock, IP);
- unsigned int gone = allstats.clients_gone; /* Reset it first because fdputsf can block */
- allstats.clients_gone = 0;
- fdputsf(clientsock, "%lu %lu %llu %llu %lu %lu %lu %lu %lu %lu\n",
- allstats.clients_current,
- allstats.clients_current + gone,
- allstats.traffic_in,
- allstats.traffic_out,
- allstats.clients,
- allstats.child_servers,
- allstats.clients_all,
- allstats.errors,
- now,
- uptime);
- }
-
- void run_netconf(unsigned int clientsock, acl_t acl, char *IP) {
- if (!acl.reconf) {
- LOGf("DENY : NetConf access denied | IP: %s\n", IP);
- send_403_forbidden(clientsock);
- return;
- }
- int nets = load_networks(config);
- if (nets > -1)
- LOGf("CONF : NetConf reloaded | IP: %s Loaded: %i\n", IP, nets);
- send_200_ok(clientsock);
- std_headers(clientsock, IP);
- if (nets > -1)
- fdputsf(clientsock,"OK %i networks read\n", nets);
- else
- fdputs(clientsock,"Networks are already up to date\n");
- }
-
- void run_chanconf(unsigned int clientsock, acl_t acl, char *IP) {
- if (!acl.reconf) {
- LOGf("DENY : ChanConf access denied | IP: %s\n", IP);
- send_403_forbidden(clientsock);
- return;
- }
- int j = load_channels(config);
- if (j > -1)
- LOGf("CONF : ChanConf reloaded | IP: %s Loaded: %i\n", IP, j);
- send_200_ok(clientsock);
- std_headers(clientsock, IP);
- if (j > -1)
- fdputsf(clientsock,"OK %i channels read\n",j);
- else
- fdputs(clientsock,"Channels are already up to date\n");
- }
-
- void run_getnetconf(unsigned int clientsock, acl_t acl, char *IP) {
- if (!acl.reconf) {
- send_403_forbidden(clientsock);
- return;
- }
- send_200_ok(clientsock);
- std_headers(clientsock, IP);
- LNODE *l, *tmp;
- list_lock(netconf);
- list_for_each(netconf, l, tmp) {
- NETWORK *n = l->data;
- fdputsf(clientsock,"%d.%d.%d.%d/%d.%d.%d.%d\t%s%s%s\n",
- (n->net >> 0 ) & 0xFF,
- (n->net >> 8 ) & 0xFF,
- (n->net >> 16) & 0xFF,
- (n->net >> 24) & 0xFF,
-
- (n->mask >> 0 ) & 0xFF,
- (n->mask >> 8 ) & 0xFF,
- (n->mask >> 16) & 0xFF,
- (n->mask >> 24) & 0xFF,
-
- n->acl.stats ? "S" : "",
- n->acl.reconf ? "F" : "",
- n->acl.access ? "A" : ""
- );
- }
- list_unlock(netconf);
- }
-
- void run_getchanconf(unsigned int clientsock, acl_t acl, char *IP) {
- if (!acl.reconf) {
- send_403_forbidden(clientsock);
- return;
- }
- send_200_ok(clientsock);
- std_headers(clientsock, IP);
- LNODE *l, *tmp;
- list_lock(chanconf);
- list_for_each(chanconf, l, tmp) {
- CHANNEL *c = l->data;
- int r = 0;
- while (c->sources[r] && r < MAX_CHANNEL_SOURCES) {
- fdputsf(clientsock,"%s\t%s\n", c->name, c->sources[r]);
- r++;
- }
- }
- list_unlock(chanconf);
- }
-
- void run_channels(unsigned int clientsock, acl_t acl, char *IP) {
- time_t now = time(NULL);
- LNODE *l, *tmp;
- if (!acl.stats) {
- LOGf("DENY : Channels access denied | IP: %s\n", IP);
- send_403_forbidden(clientsock);
- return;
- }
- send_200_ok(clientsock);
- std_headers(clientsock, IP);
- list_lock(restreamer);
- list_for_each_reverse(restreamer, l, tmp) {
- RESTREAMER *r = l->data;
- time_t uptime = now - r->started;
- fdputsf(clientsock,"%-20s\t%5i\t%5li\t%5li\t%7ld\t%12lli\t%12lli\n",
- r->name,
- r->clients->items,
- r->served,
- r->connects,
- uptime,
- r->traffic_in,
- r->traffic_out
- );
- }
- list_unlock(restreamer);
- }
|