Main Page | Data Structures | Directories | File List | Data Fields

wifidog-1.1.1/src/ping_thread.c

00001 /********************************************************************\
00002  * This program is free software; you can redistribute it and/or    *
00003  * modify it under the terms of the GNU General Public License as   *
00004  * published by the Free Software Foundation; either version 2 of   *
00005  * the License, or (at your option) any later version.              *
00006  *                                                                  *
00007  * This program is distributed in the hope that it will be useful,  *
00008  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
00009  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
00010  * GNU General Public License for more details.                     *
00011  *                                                                  *
00012  * You should have received a copy of the GNU General Public License*
00013  * along with this program; if not, contact:                        *
00014  *                                                                  *
00015  * Free Software Foundation           Voice:  +1-617-542-5942       *
00016  * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
00017  * Boston, MA  02111-1307,  USA       gnu@gnu.org                   *
00018  *                                                                  *
00019 \********************************************************************/
00020 
00021 /* $Header: /cvsroot/wifidog/wifidog/src/ping_thread.c,v 1.27 2005/03/07 04:50:25 minaguib Exp $ */
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                 /* Make sure we check the servers at the very begining */
00078                 debug(LOG_DEBUG, "Running ping()");
00079                 ping();
00080                 
00081                 /* Sleep for config.checkinterval seconds... */
00082                 timeout.tv_sec = time(NULL) + config_get_config()->checkinterval;
00083                 timeout.tv_nsec = 0;
00084 
00085                 /* Mutex must be locked for pthread_cond_timedwait... */
00086                 pthread_mutex_lock(&cond_mutex);
00087                 
00088                 /* Thread safe "sleep" */
00089                 pthread_cond_timedwait(&cond, &cond_mutex, &timeout);
00090 
00091                 /* No longer needs to be locked */
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                  * No auth servers for me to talk to
00120                  */
00121                 return;
00122         }
00123 
00124         /*
00125          * Populate uptime, memfree and load
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                                 /* Not on this line */
00135                                 while (!feof(fh) && fgetc(fh) != '\n');
00136                         }
00137                         else {
00138                                 /* Found it */
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          * Prep & send request
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; /* XXX magic... 30 second */
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                                 /* FIXME */
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                         /* FIXME */
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                         /* FIXME */
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                 /* FIXME */
00225         }
00226         else {
00227                 debug(LOG_DEBUG, "Auth Server Says: Pong");
00228         }
00229 
00230         return; 
00231 }

Generated on Sun Apr 3 20:04:46 2005 for WifiDog by  doxygen 1.4.1