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

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 /* $Id: ping_thread.c 901 2006-01-17 18:58:13Z mina $ */
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 extern time_t started_time;
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         while (1) {
00068                 /* Make sure we check the servers at the very begining */
00069                 debug(LOG_DEBUG, "Running ping()");
00070                 ping();
00071                 
00072                 /* Sleep for config.checkinterval seconds... */
00073                 timeout.tv_sec = time(NULL) + config_get_config()->checkinterval;
00074                 timeout.tv_nsec = 0;
00075 
00076                 /* Mutex must be locked for pthread_cond_timedwait... */
00077                 pthread_mutex_lock(&cond_mutex);
00078                 
00079                 /* Thread safe "sleep" */
00080                 pthread_cond_timedwait(&cond, &cond_mutex, &timeout);
00081 
00082                 /* No longer needs to be locked */
00083                 pthread_mutex_unlock(&cond_mutex);
00084         }
00085 }
00086 
00090 static void
00091 ping(void)
00092 {
00093         size_t                  numbytes,
00094                                 totalbytes;
00095         int                     sockfd, nfds, done;
00096         char                    request[MAX_BUF];
00097         fd_set                  readfds;
00098         struct timeval          timeout;
00099         FILE * fh;
00100         unsigned long int sys_uptime  = 0;
00101         unsigned int      sys_memfree = 0;
00102         float             sys_load    = 0;
00103 
00104 
00105         debug(LOG_DEBUG, "Entering ping()");
00106         
00107         sockfd = connect_auth_server();
00108         if (sockfd == -1) {
00109                 /*
00110                  * No auth servers for me to talk to
00111                  */
00112                 return;
00113         }
00114 
00115         /*
00116          * Populate uptime, memfree and load
00117          */
00118         if ((fh = fopen("/proc/uptime", "r"))) {
00119                 fscanf(fh, "%lu", &sys_uptime);
00120                 fclose(fh);
00121         }
00122         if ((fh = fopen("/proc/meminfo", "r"))) {
00123                 while (!feof(fh)) {
00124                         if (fscanf(fh, "MemFree: %u", &sys_memfree) == 0) {
00125                                 /* Not on this line */
00126                                 while (!feof(fh) && fgetc(fh) != '\n');
00127                         }
00128                         else {
00129                                 /* Found it */
00130                                 break;
00131                         }
00132                 }
00133                 fclose(fh);
00134         }
00135         if ((fh = fopen("/proc/loadavg", "r"))) {
00136                 fscanf(fh, "%f", &sys_load);
00137                 fclose(fh);
00138         }
00139 
00140         /*
00141          * Prep & send request
00142          */
00143         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\r\n"
00144                         "User-Agent: WiFiDog %s\r\n"
00145                         "Host: %s\r\n"
00146                         "\r\n",
00147                         config_get_config()->auth_servers->authserv_path,
00148                         config_get_config()->gw_id,
00149                         sys_uptime,
00150                         sys_memfree,
00151                         sys_load,
00152                         (long unsigned int)((long unsigned int)time(NULL) - (long unsigned int)started_time),
00153                         VERSION,
00154                         config_get_config()->auth_servers->authserv_hostname);
00155 
00156         debug(LOG_DEBUG, "HTTP Request to Server: [%s]", request);
00157         
00158         send(sockfd, request, strlen(request), 0);
00159 
00160         debug(LOG_DEBUG, "Reading response");
00161         
00162         numbytes = totalbytes = 0;
00163         done = 0;
00164         do {
00165                 FD_ZERO(&readfds);
00166                 FD_SET(sockfd, &readfds);
00167                 timeout.tv_sec = 30; /* XXX magic... 30 second */
00168                 timeout.tv_usec = 0;
00169                 nfds = sockfd + 1;
00170 
00171                 nfds = select(nfds, &readfds, NULL, NULL, &timeout);
00172 
00173                 if (nfds > 0) {
00176                         numbytes = read(sockfd, request + totalbytes, MAX_BUF - (totalbytes + 1));
00177                         if (numbytes < 0) {
00178                                 debug(LOG_ERR, "An error occurred while reading from auth server: %s", strerror(errno));
00179                                 /* FIXME */
00180                                 close(sockfd);
00181                                 return;
00182                         }
00183                         else if (numbytes == 0) {
00184                                 done = 1;
00185                         }
00186                         else {
00187                                 totalbytes += numbytes;
00188                                 debug(LOG_DEBUG, "Read %d bytes, total now %d", numbytes, totalbytes);
00189                         }
00190                 }
00191                 else if (nfds == 0) {
00192                         debug(LOG_ERR, "Timed out reading data via select() from auth server");
00193                         /* FIXME */
00194                         close(sockfd);
00195                         return;
00196                 }
00197                 else if (nfds < 0) {
00198                         debug(LOG_ERR, "Error reading data via select() from auth server: %s", strerror(errno));
00199                         /* FIXME */
00200                         close(sockfd);
00201                         return;
00202                 }
00203         } while (!done);
00204         close(sockfd);
00205 
00206         debug(LOG_DEBUG, "Done reading reply, total %d bytes", totalbytes);
00207 
00208         request[totalbytes] = '\0';
00209 
00210         debug(LOG_DEBUG, "HTTP Response from Server: [%s]", request);
00211         
00212         if (strstr(request, "Pong") == 0) {
00213                 debug(LOG_WARNING, "Auth server did NOT say pong!");
00214                 /* FIXME */
00215         }
00216         else {
00217                 debug(LOG_DEBUG, "Auth Server Says: Pong");
00218         }
00219 
00220         return; 
00221 }

Generated on Tue Jan 31 23:13:16 2006 for WifiDog by  doxygen 1.4.4