00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00027 #define _GNU_SOURCE
00028
00029 #include <stdio.h>
00030 #include <stdlib.h>
00031 #include <pthread.h>
00032 #include <string.h>
00033 #include <stdarg.h>
00034 #include <sys/types.h>
00035 #include <sys/socket.h>
00036 #include <netinet/in.h>
00037 #include <arpa/inet.h>
00038 #include <netdb.h>
00039 #include <unistd.h>
00040 #include <syslog.h>
00041 #include <signal.h>
00042 #include <errno.h>
00043
00044 #include "../config.h"
00045 #include "safe.h"
00046 #include "common.h"
00047 #include "conf.h"
00048 #include "debug.h"
00049 #include "ping_thread.h"
00050 #include "util.h"
00051
00052 static void ping(void);
00053
00054 time_t started_time = 0;
00055
00060 void
00061 thread_ping(void *arg)
00062 {
00063 pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
00064 pthread_mutex_t cond_mutex = PTHREAD_MUTEX_INITIALIZER;
00065 struct timespec timeout;
00066
00067 if (!started_time) {
00068 debug(LOG_INFO, "Setting started_time");
00069 started_time = time(NULL);
00070 }
00071 else if (started_time < MINIMUM_STARTED_TIME) {
00072 debug(LOG_WARNING, "Detected possible clock skew - re-setting started_time");
00073 started_time = time(NULL);
00074 }
00075
00076 while (1) {
00077
00078 debug(LOG_DEBUG, "Running ping()");
00079 ping();
00080
00081
00082 timeout.tv_sec = time(NULL) + config_get_config()->checkinterval;
00083 timeout.tv_nsec = 0;
00084
00085
00086 pthread_mutex_lock(&cond_mutex);
00087
00088
00089 pthread_cond_timedwait(&cond, &cond_mutex, &timeout);
00090
00091
00092 pthread_mutex_unlock(&cond_mutex);
00093 }
00094 }
00095
00099 static void
00100 ping(void)
00101 {
00102 size_t numbytes,
00103 totalbytes;
00104 int sockfd, nfds, done;
00105 char request[MAX_BUF];
00106 fd_set readfds;
00107 struct timeval timeout;
00108 FILE * fh;
00109 unsigned long int sys_uptime = 0;
00110 unsigned int sys_memfree = 0;
00111 float sys_load = 0;
00112
00113
00114 debug(LOG_DEBUG, "Entering ping()");
00115
00116 sockfd = connect_auth_server();
00117 if (sockfd == -1) {
00118
00119
00120
00121 return;
00122 }
00123
00124
00125
00126
00127 if ((fh = fopen("/proc/uptime", "r"))) {
00128 fscanf(fh, "%lu", &sys_uptime);
00129 fclose(fh);
00130 }
00131 if ((fh = fopen("/proc/meminfo", "r"))) {
00132 while (!feof(fh)) {
00133 if (fscanf(fh, "MemFree: %u", &sys_memfree) == 0) {
00134
00135 while (!feof(fh) && fgetc(fh) != '\n');
00136 }
00137 else {
00138
00139 break;
00140 }
00141 }
00142 fclose(fh);
00143 }
00144 if ((fh = fopen("/proc/loadavg", "r"))) {
00145 fscanf(fh, "%f", &sys_load);
00146 fclose(fh);
00147 }
00148
00149
00150
00151
00152 snprintf(request, sizeof(request) - 1, "GET %sping/?gw_id=%s&sys_uptime=%lu&sys_memfree=%u&sys_load=%.2f&wifidog_uptime=%lu HTTP/1.0\n"
00153 "User-Agent: WiFiDog %s\n"
00154 "Host: %s\n"
00155 "\n",
00156 config_get_config()->auth_servers->authserv_path,
00157 config_get_config()->gw_id,
00158 sys_uptime,
00159 sys_memfree,
00160 sys_load,
00161 (long unsigned int)((long unsigned int)time(NULL) - (long unsigned int)started_time),
00162 VERSION,
00163 config_get_config()->auth_servers->authserv_hostname);
00164
00165 debug(LOG_DEBUG, "HTTP Request to Server: [%s]", request);
00166
00167 send(sockfd, request, strlen(request), 0);
00168
00169 debug(LOG_DEBUG, "Reading response");
00170
00171 numbytes = totalbytes = 0;
00172 done = 0;
00173 do {
00174 FD_ZERO(&readfds);
00175 FD_SET(sockfd, &readfds);
00176 timeout.tv_sec = 30;
00177 timeout.tv_usec = 0;
00178 nfds = sockfd + 1;
00179
00180 nfds = select(nfds, &readfds, NULL, NULL, &timeout);
00181
00182 if (nfds > 0) {
00185 numbytes = read(sockfd, request + totalbytes,
00186 MAX_BUF - (totalbytes + 1));
00187 if (numbytes < 0) {
00188 debug(LOG_ERR, "An error occurred while reading from auth server: %s", strerror(errno));
00189
00190 close(sockfd);
00191 return;
00192 }
00193 else if (numbytes == 0) {
00194 done = 1;
00195 }
00196 else {
00197 totalbytes += numbytes;
00198 debug(LOG_DEBUG, "Read %d bytes, total now %d", numbytes, totalbytes);
00199 }
00200 }
00201 else if (nfds == 0) {
00202 debug(LOG_ERR, "Timed out reading data via select() from auth server");
00203
00204 close(sockfd);
00205 return;
00206 }
00207 else if (nfds < 0) {
00208 debug(LOG_ERR, "Error reading data via select() from auth server: %s", strerror(errno));
00209
00210 close(sockfd);
00211 return;
00212 }
00213 } while (!done);
00214 close(sockfd);
00215
00216 debug(LOG_DEBUG, "Done reading reply, total %d bytes", totalbytes);
00217
00218 request[totalbytes] = '\0';
00219
00220 debug(LOG_DEBUG, "HTTP Response from Server: [%s]", request);
00221
00222 if (strstr(request, "Pong") == 0) {
00223 debug(LOG_WARNING, "Auth server did NOT say pong!");
00224
00225 }
00226 else {
00227 debug(LOG_DEBUG, "Auth Server Says: Pong");
00228 }
00229
00230 return;
00231 }