option(USE_POLARSSL_TESTCERT "Link to the PolarSSL test certificate and key." OFF)
option(USE_POLARSSL_HAVEGE "Use the PolarSSL HAVEGE random generator key." OFF)
+option(USE_SHAREDMEMORY_API "Compile with Sharedmemory API support" OFF)
+
if(USE_POLARSSL_TESTCERT OR USE_POLARSSL_HAVEGE)
if(SSL MATCHES "openssl" OR SSL MATCHES "gnutls")
message(FATAL_ERROR "Selecting USE_POLARSSL_TESTCERT or USE_POLARSSL_HAVEGE implies SSL=polarssl")
# Configure options.
AC_ARG_WITH([ssl], [AC_HELP_STRING([--with-ssl=@<:@LIB@:>@], [SSL library (openssl|polarssl) @<:@default=polarssl@:>@])], [], [with_ssl=polarssl])
+AC_ARG_ENABLE([shmapi], [AC_HELP_STRING([--enable-shmapi], [compile with Sharedmemory API support @<:@default=no@:>@])],[],[enable_shmapi=no] )
AC_ARG_ENABLE(polarssl-test-cert, [ --enable-polarssl-test-cert Link to PolarSSL test certificate and key @<:@default=no@:>@], [enable_polarssl_test_cert=yes])
-AC_ARG_ENABLE(polarssl-havege, [ --enable-polarssl-havege Link to PolarSSL HAVEGE random generator key @<:@default=no@:>@ Deafult: /dev/urandom], [enable_polarssl_havege=yes])
+AC_ARG_ENABLE(polarssl-havege, [ --enable-polarssl-havege Link to PolarSSL HAVEGE random generator key @<:@default=no@:>@ Default: /dev/urandom], [enable_polarssl_havege=yes])
+
+
+
# Checks for programs.
AC_PROG_CC
AM_CONDITIONAL(USE_OPENSSL, test x$with_ssl = xopenssl)
AM_CONDITIONAL(USE_GNUTLS, test x$with_ssl = xgnutls)
+AS_IF([test "x$enable_shmapi" != xno],
+ [
+ AM_CONDITIONAL(USE_SHAREDMEMORY_API, true)
+ AC_DEFINE([USE_SHAREDMEMORY_API],[],[Use sharedmemory API])
+ ], [
+ AM_CONDITIONAL(USE_SHAREDMEMORY_API, false)
+])
+
+
+
AC_DEFINE([DEFAULT_CONFIG], ["/etc/umurmur.conf"], [Default config])
# Checks for header files.
--- /dev/null
+* BUG_FIX: Fix the screen not clearing when last person exits the server \r
+\r
+\r
+* Code clean up\r
+\r
+\r
+* Added more client data 99% of the useful client data shown\r
+* rework Sharedmemory_update() to not use memcpy (requested by fatbob)\r
+\r
+\r
+* Using a more modern unix sharedmemory API. this requires linking with librt.so (requested by fatbob)\r
+* Added away to know if umurmurd is not connected/updateing the shm_t struct. I use 8bit timer with \r
+ rollover protection see check_serverTick() and where I use the function near bottum of mon-umurmurd.c \r
+ for how to use this.\r
+\r
+\r
+* code clean up and some comments added\r
+* ~95% of the useful client data shown\r
+* outputs a more meaningful idle and online time, both are reported in secs (error reported by fatbob)\r
--- /dev/null
+#############################################################################
+#
+# Makefile for mon-umurmurd
+
+
+# The recommended compiler flags for the Raspberry Pi
+#CCFLAGS=-Wall -Ofast -mfpu=vfp -mfloat-abi=hard -march=armv6zk -mtune=arm1176jzf-s -g -lrt
+CCFLAGS= -lrt
+
+# define all programs
+PROGRAMS = mon-umurmurd
+SOURCES = ${PROGRAMS:=.c}
+
+all: ${PROGRAMS}
+
+${PROGRAMS}: ${SOURCES}
+ gcc ${CCFLAGS} $@.c -o $@
+
+clean:
+ rm -rf $(PROGRAMS)
+
+install: all
+ cp mon-umurmurd /usr/local/bin/
+
+.PHONY: install
--- /dev/null
+mon-umurmurd\r
+============\r
+\r
+outputs server/client data to term useing the sharedmemory API added to umurmur for testing\r
+\r
+make\r
+./mon-umurmurd\r
--- /dev/null
+#include <fcntl.h> /* For O_* constants */\r
+#include <stdio.h>\r
+#include <ctype.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <unistd.h>\r
+#include <sys/stat.h>\r
+#include <sys/mman.h>\r
+#include <sys/types.h>\r
+#include "../../src/sharedmemory.h"\r
+#include "../../src/sharedmemory_global.h"\r
+\r
+enum{ NOP_SHM, WAIT_ATTACH_SHM, TRY_ATTACH_SHM, MAT_SHM, CLEAN_UP_SHM, RUN_SHM };\r
+\r
+int wait = 0, opt;\r
+uint8_t last, shm_statem = TRY_ATTACH_SHM;\r
+\r
+void run_shm(void);\r
+\r
+int main(int argc, char **argv) \r
+{\r
+ struct stat buf;\r
+ int bindport = 0;\r
+ \r
+ while ( (opt = getopt(argc, argv, "wb:")) != -1 ) \r
+ {\r
+ switch(opt) \r
+ {\r
+ case 'w':\r
+ wait = 1;\r
+ break;\r
+ case 'b':\r
+ bindport = atoi(optarg);\r
+ break; \r
+ default: \r
+ fprintf(stderr, "Usage: %s [-w] [-b <port>]\n", argv[0]);\r
+ fprintf(stderr, "\t-w - Wait for umurmurd to create shm area. useful if you need to start from init.d script\n" );\r
+ fprintf(stderr, "\t-b <port> - Change this to the port used when starting umurmurd. Defaults to \"/umurmurd:64738\" \n");\r
+ exit(EXIT_FAILURE);\r
+ }\r
+ }\r
+\r
+ shmptr = NULL;\r
+ \r
+ if( !bindport )\r
+ {\r
+ bindport = 64738;\r
+ }\r
+ \r
+ sprintf( shm_file_name, "/umurmurd:%i", bindport );\r
+ \r
+ if( wait )\r
+ shm_statem = WAIT_ATTACH_SHM;\r
+ \r
+ while( shm_statem )\r
+ {\r
+ switch( shm_statem )\r
+ {\r
+ case RUN_SHM:\r
+ run_shm();\r
+ break; \r
+ case WAIT_ATTACH_SHM:\r
+ printf( "Waiting for umurmurd to be run\n\r"); fflush(stdout);\r
+ while( ( shm_fd = shm_open( shm_file_name, O_RDONLY, 0666 ) ) == -1 )\r
+ sleep( 1 );\r
+ shm_statem = MAT_SHM;\r
+ break;\r
+ case TRY_ATTACH_SHM:\r
+ if( ( shm_fd = shm_open( shm_file_name, O_RDONLY, 0666 ) ) == -1 )\r
+ {\r
+ printf( "umurmurd doesn't seem to be running\n\r" ); \r
+ exit(EXIT_FAILURE);\r
+ }\r
+ shm_statem = MAT_SHM;\r
+ break;\r
+ case MAT_SHM: \r
+ fstat( shm_fd, &buf); \r
+ if( ( shmptr = mmap(0, buf.st_size, PROT_READ, MAP_SHARED, shm_fd, 0) ) == MAP_FAILED ) \r
+ {\r
+ exit(EXIT_FAILURE);\r
+ } \r
+ printf( "umumurd PID: %u\n\r", shmptr->umurmurd_pid );\r
+ shm_statem = RUN_SHM; \r
+ break;\r
+ case CLEAN_UP_SHM: \r
+ \r
+ break;\r
+ \r
+ }\r
+ }\r
+ fflush(stdout);\r
+ return 0;\r
+}\r
+\r
+uint8_t check_serverTick(void)\r
+{\r
+ last = shmptr->alive;\r
+ sleep( 1 ); // Sleep for 1 sec\r
+ return(shmptr->alive - last); \r
+}\r
+\r
+void run_shm(void)\r
+{\r
+\r
+int cc;\r
+\r
+ printf( "\033[2J\033[H" ); fflush(stdout); //clear screen VT100\r
+ printf( "%s Clients(CONECTED/MAX) %i/%i\n\n", shm_file_name, shmptr->clientcount, shmptr->server_max_clients ); \r
+ \r
+ for( cc = 0 ; cc < shmptr->server_max_clients ; cc++ )\r
+ {\r
+ \r
+ if( !shmptr->client[cc].authenticated )\r
+ continue; \r
+ \r
+ printf( "%s@%s:%i in channel: %s\n\\r
+ \tclient_OS: %s %s\n\\r
+ \tclient_info: %s\n\\r
+ \tavailableBandwidth: %i\n\\r
+ \tOnline(secs): %lu Idle(secs): %lu\n\\r
+ \tusingUDP=%i\n\\r
+ \tdeaf=%i, mute=%i\n\\r
+ \tself_deaf=%i, self_mute=%i\n\\r
+ \trecording=%i\n\\r
+ \tbOpus=%i\n\\r
+ \tisAdmin=%i\n\\r
+ \tisSuppressed=%i\n\\r
+ \tUDP_Avg/Var: %3.2f/%3.2f\n\\r
+ \tTCP_Avg/Var: %3.2f/%3.2f\n\\r
+ \tUDP_C/TCP_C: %lu/%lu\n", \r
+ shmptr->client[cc].username,\r
+ shmptr->client[cc].ipaddress,\r
+ shmptr->client[cc].udp_port,\r
+ shmptr->client[cc].channel,\r
+ shmptr->client[cc].os,\r
+ shmptr->client[cc].os_version,\r
+ shmptr->client[cc].release,\r
+ shmptr->client[cc].availableBandwidth,\r
+ shmptr->client[cc].online_secs,\r
+ shmptr->client[cc].idle_secs,\r
+ \r
+ shmptr->client[cc].bUDP,\r
+ shmptr->client[cc].deaf,\r
+ shmptr->client[cc].mute,\r
+ shmptr->client[cc].self_deaf,\r
+ shmptr->client[cc].self_mute,\r
+ shmptr->client[cc].recording,\r
+ shmptr->client[cc].bOpus,\r
+ \r
+ shmptr->client[cc].isAdmin,\r
+ shmptr->client[cc].isSuppressed,\r
+ \r
+ shmptr->client[cc].UDPPingAvg,\r
+ shmptr->client[cc].UDPPingVar,\r
+ shmptr->client[cc].TCPPingAvg,\r
+ shmptr->client[cc].TCPPingVar,\r
+ shmptr->client[cc].UDPPackets,\r
+ shmptr->client[cc].TCPPackets ); fflush(stdout); // fflush need because of sleep() call\r
+ }\r
+ if( !check_serverTick() )\r
+ {\r
+ exit(EXIT_FAILURE); //You dont have to exit you could just report the fact that the data is not valid \r
+ }\r
+}
\ No newline at end of file
list(APPEND SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/ssli_gnutls.c)
endif(SSL MATCHES "openssl")
+if(USE_SHAREDMEMORY_API)
+ list(APPEND SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/sharedmemory.c)
+endif(USE_SHAREDMEMORY_API)
+
set(SOURCE ${SOURCE} ${SOURCE_FILES} PARENT_SCOPE)
umurmurd_SOURCES+=ssli_polarssl.c
endif
endif
+
+if USE_SHAREDMEMORY_API
+umurmurd_SOURCES+=sharedmemory.c
+endif
#cmakedefine USE_POLARSSL
#cmakedefine USE_POLARSSL_TESTCERT
#cmakedefine USE_POLARSSL_HAVEGE
+
+#cmakedefine USE_SHAREDMEMORY_API
+
#define DEFAULT_CONFIG "${CMAKE_INSTALL_PREFIX}/etc/umurmur.conf"
#endif // CONFIG_H
#include "conf.h"
#include "version.h"
#include "config.h"
+#include "sharedmemory.h"
char system_string[64], version_string[64];
int bindport;
Chan_init();
Client_init();
Ban_init();
-
+
+#ifdef USE_SHAREDMEMORY_API
+ Sharedmemory_init( bindport, bindport6 );
+#endif
+
#ifdef POSIX_PRIORITY_SCHEDULING
if (realtime)
setscheduler();
Server_run();
+#ifdef USE_SHAREDMEMORY_API
+ Sharedmemory_deinit();
+#endif
+
Ban_deinit();
SSLi_deinit();
Chan_free();
while (!shutdown_server) {
struct sockaddr_storage remote;
int i;
+
+#ifdef USE_SHAREDMEMORY_API
+ Sharedmemory_alivetick();
+#endif
for(i = 0; i < nofServerSocks; i++) {
pollfds[i].revents = 0;
if (pollfds[nofServerSocks + i].revents & POLLOUT)
Client_write_fd(pollfds[nofServerSocks + i].fd);
}
+#ifdef USE_SHAREDMEMORY_API
+ Sharedmemory_update();
+#endif
}
}
--- /dev/null
+#include "sharedmemory.h"\r
+#include "sharedmemory_global.h"\r
+\r
+void Sharedmemory_init( int bindport, int bindport6 ) \r
+{\r
+ \r
+ int server_max_clients = getIntConf(MAX_CLIENTS); \r
+ int shmtotal_size = sizeof( shm_t ) + (sizeof( shmclient_t ) * server_max_clients);\r
+\r
+ if( !bindport )\r
+ {\r
+ bindport = getIntConf(BINDPORT); \r
+ }\r
+\r
+ sprintf( shm_file_name, "/umurmurd:%i", bindport );\r
+ Log_info("SHM_API: shm_fd=\"%s\"", shm_file_name );\r
+\r
+ shm_fd = shm_open( shm_file_name, O_CREAT | O_RDWR, 0660 );\r
+ if(shm_fd == -1)\r
+ {\r
+ Log_fatal( "SHM_API: Open failed:%s\n", strerror(errno));\r
+ exit(EXIT_FAILURE);\r
+ } \r
+\r
+ if( ftruncate( shm_fd, shmtotal_size ) == -1 )\r
+ {\r
+ Log_fatal( "SHM_API: ftruncate : %s\n", strerror(errno)); \r
+ exit(EXIT_FAILURE);\r
+ }\r
+\r
+ shmptr = mmap( 0, shmtotal_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0 );\r
+ if (shmptr == MAP_FAILED) \r
+ {\r
+ Log_fatal( "SHM_API: mmap failed : %s\n", strerror(errno));\r
+ exit(EXIT_FAILURE);\r
+ } \r
+\r
+ memset( shmptr, 0, shmtotal_size );\r
+\r
+ shmptr->umurmurd_pid = getpid();\r
+ shmptr->server_max_clients = server_max_clients; \r
+ shmptr->shmtotal_size = shmtotal_size;\r
+ shmptr->shmclient_size = sizeof( shmclient_t ) * shmptr->server_max_clients; \r
+ \r
+}\r
+\r
+void Sharedmemory_update(void) \r
+{\r
+\r
+ uint64_t now;\r
+ unsigned int cc = 0;\r
+ client_t *client_itr = NULL;\r
+\r
+ memset( &shmptr->client[0], 0, shmptr->shmclient_size );\r
+ shmptr->clientcount = Client_count();\r
+ \r
+ if( shmptr->clientcount )\r
+ {\r
+ Timer_init( &now );\r
+ while( Client_iterate(&client_itr) != NULL )\r
+ { \r
+ if( client_itr->authenticated )\r
+ { \r
+ channel_t *channel = client_itr->channel;\r
+ \r
+ strncpy( shmptr->client[cc].username, client_itr->username, 120 );\r
+ strncpy( shmptr->client[cc].ipaddress, Util_clientAddressToString( client_itr ), INET6_ADDRSTRLEN - 1 );\r
+ strncpy( shmptr->client[cc].channel, channel->name, 120 );\r
+ \r
+ strncpy( shmptr->client[cc].os, client_itr->os, 120 );\r
+ strncpy( shmptr->client[cc].release, client_itr->release, 120 );\r
+ strncpy( shmptr->client[cc].os_version, client_itr->os_version, 120 );\r
+ \r
+ shmptr->client[cc].tcp_port = Util_clientAddressToPortTCP( client_itr );\r
+ shmptr->client[cc].udp_port = Util_clientAddressToPortUDP( client_itr ); \r
+ \r
+ shmptr->client[cc].online_secs = ( now - client_itr->connectTime ) / 1000000LL;\r
+ shmptr->client[cc].idle_secs = ( now - client_itr->idleTime ) / 1000000LL;\r
+ \r
+ shmptr->client[cc].bUDP = client_itr->bUDP;\r
+ shmptr->client[cc].deaf = client_itr->deaf;\r
+ shmptr->client[cc].mute = client_itr->mute;\r
+ shmptr->client[cc].bOpus = client_itr->bOpus;\r
+ shmptr->client[cc].self_deaf = client_itr->self_deaf;\r
+ shmptr->client[cc].self_mute = client_itr->self_mute;\r
+ shmptr->client[cc].recording = client_itr->recording;\r
+ shmptr->client[cc].authenticated = client_itr->authenticated;\r
+ \r
+ shmptr->client[cc].availableBandwidth = client_itr->availableBandwidth;\r
+ \r
+ shmptr->client[cc].UDPPingAvg = client_itr->UDPPingAvg;\r
+ shmptr->client[cc].UDPPingVar = client_itr->UDPPingVar;\r
+ shmptr->client[cc].TCPPingAvg = client_itr->TCPPingAvg;\r
+ shmptr->client[cc].TCPPingVar = client_itr->TCPPingVar;\r
+ \r
+ shmptr->client[cc].isAdmin = client_itr->isAdmin;\r
+ shmptr->client[cc].isSuppressed = client_itr->isSuppressed;\r
+ \r
+ shmptr->client[cc].UDPPackets = client_itr->UDPPackets;\r
+ shmptr->client[cc].TCPPackets = client_itr->TCPPackets;\r
+ \r
+ } \r
+ cc++; \r
+ }\r
+ } \r
+}\r
+void Sharedmemory_alivetick(void)\r
+{\r
+ shmptr->alive++;\r
+}\r
+\r
+void Sharedmemory_deinit(void) \r
+{\r
+ close( shm_fd );\r
+ shm_unlink( shm_file_name );\r
+ shmptr->umurmurd_pid = 0;\r
+}
\ No newline at end of file
--- /dev/null
+#ifndef SHAREDMEMORY_H_777736932196\r
+#define SHAREDMEMORY_H_777736932196\r
+\r
+#include <stdlib.h>\r
+#include <string.h>\r
+\r
+#include <fcntl.h> /* For O_* constants */ \r
+#include <unistd.h>\r
+#include <sys/mman.h>\r
+\r
+#include <netinet/in.h>\r
+#include "util.h"\r
+#include "conf.h" \r
+#include "client.h"\r
+#include "channel.h"\r
+#include "sharedmemory_struct.h" \r
+\r
+void Sharedmemory_init( int bindport, int bindport6 );\r
+void Sharedmemory_update(void);\r
+void Sharedmemory_alivetick(void);\r
+void Sharedmemory_deinit(void);\r
+\r
+#endif // SHAREDMEMORY_H_777736932196
\ No newline at end of file
--- /dev/null
+int shm_fd;\r
+shm_t *shmptr = NULL;\r
+char shm_file_name[128];\r
--- /dev/null
+typedef struct\r
+{\r
+\r
+ char username[121];\r
+ char ipaddress[INET6_ADDRSTRLEN];\r
+ char channel[121];\r
+ char os[121], release[121], os_version[121];\r
+ int tcp_port, udp_port;\r
+ bool_t bUDP, authenticated, deaf, mute, self_deaf, self_mute, recording, bOpus;\r
+ int availableBandwidth;\r
+ uint32_t online_secs, idle_secs;\r
+ bool_t isAdmin;\r
+ bool_t isSuppressed;\r
+ float UDPPingAvg, UDPPingVar, TCPPingAvg, TCPPingVar;\r
+ uint32_t UDPPackets, TCPPackets;\r
+\r
+}shmclient_t;\r
+\r
+typedef struct\r
+{\r
+\r
+ int shmtotal_size, shmclient_size;\r
+ int clientcount, server_max_clients;\r
+ unsigned int umurmurd_pid;\r
+ uint8_t alive;\r
+ shmclient_t client[];\r
+\r
+}shm_t;\r
}
static inline void SSLi_hex2hash(char *in, uint8_t *hash)
{
- int i, offset = 0;
+ int i;
char byte[3];
int scanned;