From 01a2ebb9a402dc4c3f9183d457565685885f6fb9 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Wed, 8 Nov 2017 16:14:32 +0100 Subject: [SERVER] rpc: Add q=logfile, q=altservers and q=config to /query --- src/server/altservers.c | 30 ++++++++++++++++++++++++++++++ src/server/altservers.h | 4 ++++ src/server/rpc.c | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+) (limited to 'src/server') diff --git a/src/server/altservers.c b/src/server/altservers.c index 5644625..d0bb206 100644 --- a/src/server/altservers.c +++ b/src/server/altservers.c @@ -8,6 +8,7 @@ #include "../serverconfig.h" #include #include +#include static dnbd3_connection_t *pending[SERVER_MAX_PENDING_ALT_CHECKS]; static pthread_spinlock_t pendingLockWrite; // Lock for adding something to pending. (NULL -> nonNULL) @@ -264,6 +265,35 @@ int altservers_getListForUplink(dnbd3_host_t *output, int size, int emergency) return count; } +json_t* altservers_toJson() +{ + json_t *list = json_array(); + + spin_lock( &altServersLock ); + char host[100]; + const int count = numAltServers; + dnbd3_alt_server_t src[count]; + memcpy( src, altServers, sizeof(src) ); + spin_unlock( &altServersLock ); + for (int i = 0; i < count; ++i) { + json_t *rtts = json_array(); + for (int j = 0; j < SERVER_RTT_PROBES; ++j) { + json_array_append_new( rtts, json_integer( src[i].rtt[ (j + src[i].rttIndex + 1) % SERVER_RTT_PROBES ] ) ); + } + sock_printHost( &src[i].host, host, sizeof(host) ); + json_t *server = json_pack( "{ss,ss,so,sb,sb,si}", + "comment", src[i].comment, + "host", host, + "rtt", rtts, + "isPrivate", (int)src[i].isPrivate, + "isClientOnly", (int)src[i].isClientOnly, + "numFails", src[i].numFails + ); + json_array_append_new( list, server ); + } + return list; +} + /** * Update rtt history of given server - returns the new average for that server */ diff --git a/src/server/altservers.h b/src/server/altservers.h index e98e83c..7b7b46d 100644 --- a/src/server/altservers.h +++ b/src/server/altservers.h @@ -3,6 +3,8 @@ #include "globals.h" +struct json_t; + void altservers_init(); void altservers_shutdown(); @@ -23,4 +25,6 @@ int altservers_netCloseness(dnbd3_host_t *host1, dnbd3_host_t *host2); void altservers_serverFailed(const dnbd3_host_t * const host); +struct json_t* altservers_toJson(); + #endif /* UPLINK_CONNECTOR_H_ */ diff --git a/src/server/rpc.c b/src/server/rpc.c index ff4b0ab..c739f12 100644 --- a/src/server/rpc.c +++ b/src/server/rpc.c @@ -4,6 +4,7 @@ #include "uplink.h" #include "locks.h" #include "image.h" +#include "altservers.h" #include "../shared/sockhelper.h" #include "fileutil.h" #include "picohttpparser/picohttpparser.h" @@ -19,6 +20,9 @@ #define ACL_STATS 1 #define ACL_CLIENT_LIST 2 #define ACL_IMAGE_LIST 4 +#define ACL_CONFIG 8 +#define ACL_LOG 16 +#define ACL_ALTSERVERS 32 #define HTTP_CLOSE 4 #define HTTP_KEEPALIVE 9 @@ -250,6 +254,7 @@ static bool handleStatus(int sock, int permissions, struct field *fields, size_t { bool ok; bool stats = false, images = false, clients = false, space = false; + bool logfile = false, config = false, altservers = false; #define SETVAR(var) if ( !var && STRCMP(fields[i].value, #var) ) var = true for (size_t i = 0; i < fields_num; ++i) { if ( !equals( &fields[i].name, &STR_Q ) ) continue; @@ -257,6 +262,9 @@ static bool handleStatus(int sock, int permissions, struct field *fields, size_t else SETVAR(space); else SETVAR(images); else SETVAR(clients); + else SETVAR(logfile); + else SETVAR(config); + else SETVAR(altservers); } #undef SETVAR if ( ( stats || space ) && !(permissions & ACL_STATS) ) { @@ -268,6 +276,15 @@ static bool handleStatus(int sock, int permissions, struct field *fields, size_t if ( clients && !(permissions & ACL_CLIENT_LIST) ) { return sendReply( sock, "403 Forbidden", "text/plain", "No permission to access client list", -1, keepAlive ); } + if ( logfile && !(permissions & ACL_LOG) ) { + return sendReply( sock, "403 Forbidden", "text/plain", "No permission to access log", -1, keepAlive ); + } + if ( config && !(permissions & ACL_CONFIG) ) { + return sendReply( sock, "403 Forbidden", "text/plain", "No permission to access config", -1, keepAlive ); + } + if ( altservers && !(permissions & ACL_ALTSERVERS) ) { + return sendReply( sock, "403 Forbidden", "text/plain", "No permission to access altservers", -1, keepAlive ); + } // Call this first because it will update the total bytes sent counter json_t *jsonClients = NULL; if ( stats || clients ) { @@ -302,6 +319,25 @@ static bool handleStatus(int sock, int permissions, struct field *fields, size_t if ( images ) { json_object_set_new( statisticsJson, "images", image_getListAsJson() ); } + if ( logfile ) { + char logbuf[4000]; + ssize_t len = log_fetch( logbuf, sizeof(logbuf) ); + json_t *val; + if ( len <= 0 ) { + val = json_null(); + } else { + val = json_stringn_nocheck( logbuf, (size_t)len ); + } + json_object_set_new( statisticsJson, "logfile", val ); + } + if ( config ) { + char buf[2000]; + size_t len = globals_dumpConfig( buf, sizeof(buf) ); + json_object_set_new( statisticsJson, "config", json_stringn_nocheck( buf, len ) ); + } + if ( altservers ) { + json_object_set_new( statisticsJson, "altservers", altservers_toJson() ); + } char *jsonString = json_dumps( statisticsJson, 0 ); json_decref( statisticsJson ); -- cgit v1.2.3-55-g7522