PageRenderTime 134ms CodeModel.GetById 31ms app.highlight 95ms RepoModel.GetById 1ms app.codeStats 0ms

/monitor.cpp

https://github.com/gigablast/open-source-search-engine
C++ | 730 lines | 382 code | 110 blank | 238 comment | 62 complexity | 73ce752afd338e7fa68f9eef0ee56f4a MD5 | raw file
Possible License(s): Apache-2.0
  1// Matt Wells, copyright Feb 2003
  2
  3#include "gb-include.h"
  4
  5#include <errno.h>
  6#include <time.h>
  7#include <sys/time.h>
  8#include <netdb.h>
  9#include <sys/types.h>
 10#include <sys/socket.h>
 11#include <netinet/in.h>
 12#include "PingServer.h"
 13#include "HttpServer.h"
 14#include "Dns.h"
 15#include <sys/time.h>
 16#include <sys/resource.h>
 17
 18// Loop.h defines these to core, so fix that!
 19#undef  sleep(a)
 20#undef usleep(a)
 21
 22extern int h_errno;
 23
 24bool mainShutdown ( bool urgent ) { return true; }
 25bool closeAll ( void *state , void (* callback)(void *state) ) { return true; }
 26bool allExit ( ) { return true; }
 27
 28void checkPage ( char *host , uint16_t port , char *path ) ;
 29bool getPage ( char *host , uint16_t port , char *path ) ;
 30int connectSock ( char *host , uint16_t port ) ;
 31bool sendEmail ( char *errmsg ) ;
 32//bool sendEmailSSL ( char *errmsg ) ;
 33void sleepWrapper ( int fd , void *state ) ;
 34
 35
 36
 37// a static buf
 38static char s_errbuf [ 50024 ];
 39
 40// sample every X seconds (was 120)
 41#define WAIT 30
 42// for debugging
 43//#define WAIT 2
 44
 45static int32_t s_wait = WAIT;
 46
 47// count # of consecutive errors
 48static int32_t s_count = 0;
 49
 50// last time we sent an email
 51static time_t s_lastTime = 0;
 52
 53//static bool s_buzz = false;
 54
 55char *g_host = NULL;
 56int32_t  g_port = 80;
 57bool g_montest = false;
 58bool g_isFlurbit = false;
 59bool g_isProCog = false;
 60char *g_fqhn = "gigablast.com";
 61
 62int main ( int argc , char *argv[] ) {
 63	// debug test
 64	//sendEmail("hey you!");
 65	//return 0;
 66	//if(argc > 1 && strcmp(argv[1], "buzz") == 0) {
 67	//	s_buzz = true;
 68	//}
 69	bool badArgs = false;
 70
 71	for ( int32_t i = 2 ; i < argc ; i++ ) {
 72
 73		if ( argv[i][0]=='-' &&
 74		     argv[i][1]=='t' ) {
 75			//argc--;
 76			g_montest = true;
 77			s_wait = 1;
 78			continue;
 79		}
 80
 81		if ( i+1 < argc &&
 82		     argv[i][0]=='-' &&
 83		     argv[i][1]=='h' ) {
 84			g_fqhn = argv[i+1];
 85			i++;
 86			continue;
 87		}
 88
 89		badArgs = true;
 90	}
 91
 92
 93	if ( argc < 2 || badArgs ) {
 94		fprintf(stderr,"Usage: monitor www.xyz.com:80 [-h FQHN] [-t]\n");
 95		fprintf(stderr,"FQHN defaults to gigablast.com, but if you are"
 96			" not monitoring on gigablast's network then you "
 97			"need to set this to like monitor2.gigablast.com "
 98			"or whatever your hostname is so verizon accepts our "
 99			"email.\n");
100		exit(-1);
101	}
102
103	g_host = argv[1];
104	// scan for port
105	char *portStr = strstr(g_host,":");
106	g_port = 80;
107	if ( portStr ) {
108		g_port = atoi(portStr+1);
109		*portStr = 0;
110	}
111
112	g_isFlurbit = (bool)strstr(g_host,"flurbit.com");
113	if ( ! g_isFlurbit ) 
114		g_isFlurbit = (bool)strstr(g_host,"69.64.70.68");
115	if ( ! g_isFlurbit ) 
116		g_isFlurbit = (bool)strstr(g_host,"eventguru.com");
117	if ( ! g_isFlurbit ) 
118		g_isFlurbit = (bool)strstr(g_host,"eventwidget.com");
119
120
121	// let's ensure our core file can dump
122	struct rlimit lim;
123	lim.rlim_cur = lim.rlim_max = RLIM_INFINITY;
124	if ( setrlimit(RLIMIT_CORE,&lim) )
125		log("monitor: setrlimit: %s.", mstrerror(errno) );
126
127	g_isProCog = (bool)strstr(g_host,"procog.com");
128
129
130	g_conf.m_sendEmailAlerts              = true;
131	g_conf.m_sendEmailAlertsToSysadmin    = true;
132	//g_conf.m_sendEmailAlertsToMattAlltell = false;
133	//g_conf.m_sendEmailAlertsToJavier      = false;
134	//g_conf.m_sendEmailAlertsToPartap      = false;
135	//g_conf.m_sendEmailAlertsToZak         = false;
136	g_conf.m_delayNonCriticalEmailAlerts  = false;
137
138	// avoid any local dns, just go directly to the roots
139	//g_conf.setRootIps();
140	// no, try asking local bind9 !! seems safer... the root dns
141	// seem to go down forever after a while...
142	g_conf.m_askRootNameservers           = false;//true;
143
144	// hack # of dns servers
145	g_conf.m_numDns         = 2;//3;
146	g_conf.m_dnsPorts[0]    = 53;
147	g_conf.m_dnsPorts[1]    = 53;
148	g_conf.m_dnsPorts[2]    = 53;
149	// local bind9 server
150	//g_conf.m_dnsIps  [2]    = atoip ( "127.0.0.1",9);
151	// google open dns server
152	g_conf.m_dnsIps  [1]    = atoip ( "8.8.8.8",7);
153	//g_conf.m_dnsIps  [0]    = atoip ( "8.8.4.4",7);
154	g_conf.m_dnsIps  [0]    = atoip ( "127.0.0.1",9);
155	g_conf.m_dnsMaxCacheMem = 1024*10;
156
157	g_conf.m_logDebugDns = false;//true;
158
159	// matt wells
160	// call alltel mail server directly to send to matt in case
161	// mail.gigablast.com is down
162	// hey, it already goes directly in m_sendEmailAlertsToMattAlltell
163	// so set this to false.
164	g_conf.m_sendEmailAlertsToEmail1 = true;
165	// verizon bought us out... smtp-sl.vtext.com
166	// was messages.alltel.com
167	strcpy ( g_conf.m_email1Addr , "5054503518@vtext.com");
168	strcpy ( g_conf.m_email1From , "monitor@gigablast.com");
169	// use our email server
170	// nah, our mailserver is probably down...
171	// result of "dig MX message.alltel.com", make this canonical
172	// in case they change their IP one of these days!
173	//strcpy ( g_conf.m_email1MX   , "sms-mta.alltel.net" );
174	//strcpy ( g_conf.m_email1MX   , "smtp-sl.vtext.com");
175	// . result of "dig MX vtext.com" = smtp-bb.vtext.com
176	// . they changed this on 4/19/2013!!
177	// . prepend gbmxrec- to hostname to do an mxrec lookup
178	// . fix it :
179	//   1366500952283 000 DEBUG dns     Got CNAME alias smtp-bb.vtext.com for gbmxrec-vtext.com
180	//   1366500952283 000 DEBUG dns     Got CNAME alias smtp-sl.vtext.com for smtp-bb.vtext.com
181
182	// got ip 69.78.67.53 for 'smtp-sl.vtext.com'
183	//strcpy ( g_conf.m_email1MX   , "gbmxrec-vtext.com");
184	strcpy ( g_conf.m_email1MX   , "smtp-bb.vtext.com");
185
186	// send to zak directly
187	g_conf.m_sendEmailAlertsToEmail2 = false;//true;
188	//strcpy ( g_conf.m_email2Addr , "5052204556@message.alltel.com" );
189	//strcpy ( g_conf.m_email2Addr , "5052204556@vtext.com" );
190	//strcpy ( g_conf.m_email2From , "monitor@gigablast.com");
191	// got this ip from the cmd:
192	// dig mx message.alltel.com 
193	//strcpy ( g_conf.m_email2MX   , "166.102.165.62" );
194	//strcpy ( g_conf.m_email2MX   , "sms-mta.alltel.net" );
195	//strcpy ( g_conf.m_email2MX   , "smtp-sl.vtext.com");
196
197	// to sabino right to his email server
198	//g_conf.m_sendEmailAlertsToEmail3 = true;
199	//strcpy ( g_conf.m_email3Addr , "7082076550@mobile.mycingular.com");
200	//strcpy ( g_conf.m_email3From , "sysadmin@comcastbusiness.net" );
201	// "mx.mycingular.net"
202	//strcpy ( g_conf.m_email3MX   , "66.102.164.222");
203
204	//partap
205	g_conf.m_sendEmailAlertsToEmail3 = false;//true;
206	//strcpy ( g_conf.m_email3Addr , "5056889554@txt.att.net");
207	strcpy ( g_conf.m_email3Addr , "sysadmin@gigablast.com" );
208	strcpy ( g_conf.m_email3From , "sysadmin@gigablast.com" );
209	//strcpy ( g_conf.m_email3MX   , "66.231.188.229");
210	strcpy ( g_conf.m_email3MX   , "10.6.54.47");
211
212	
213	g_conf.m_httpMaxSockets               = 100;
214
215	g_loop.init();
216
217	hashinit();
218
219	// use -1 or 0 for port to avoid setting up the server, just client
220	g_httpServer.init ( -1 , -1 );
221
222	g_loop.registerSleepCallback ( 10 , // WAIT * 1000 ,
223				       NULL ,
224				       sleepWrapper );
225
226	if ( ! g_dns.init( 9532 ) ) return 1;
227
228	if ( ! g_loop.runLoop() ) return 1;
229}
230
231// have a list of queries we cycle through
232int32_t g_qn = 0;
233
234char *g_queries[] = {
235	//"buzzlogic",
236	"broncos",
237	"ibm",
238	"yahoo",
239	//"buzzlogic",
240	"google",
241	"amazon",
242	//"ebay",
243	NULL
244};
245
246#define TYPE_GB   0
247#define TYPE_BUZZ 1
248
249char g_type[] = {
250	//1, // buzzlogic
251	//0, // test
252	0 , // broncos
253	0, // ibm
254	0, // yahoo
255	//1, // buzzlogic
256	0,
257	0,
258	//0,
259	0
260};
261
262// . need to contain these substrings in the result page
263// . added quote because they need to be in an href="xxx" tag
264#define MAX_SUBSTRINGS 7
265char *g_substrings[][MAX_SUBSTRINGS] = {
266	// just for buzz
267	//{"buzzlogic.com/",NULL},
268
269	// broncos
270	{"denverpost.com/broncos",
271	 "denverbroncos.com"},
272
273	// test
274	//{"testpreview.com","test.com",
275	// "toefl.org","tmworld.com","collegeboard.com",
276	// "en.wikipedia.org" , NULL } ,
277
278	// ibm
279	{"http://www.ibm.com/",
280	 "http://en.wikipedia.org/",
281	 "http://research.ibm.com/", NULL},
282	// yahoo
283	{"http://www.yahoo.com/",NULL},
284	// just for buzz
285	//{"buzzlogic.com/",NULL},
286	// google
287	{"http://www.google.com/",NULL},
288	// amazon
289	{"http://www.amazon.com/",NULL},
290	// ebay
291	//{"href=http://www.ebay.com/>",NULL},
292	// ... add more here...
293};
294
295static int32_t s_goodMXIp = 0;
296
297
298void gotMXIpWrapper ( void *state , int32_t ip ) {
299	g_conf.m_logDebugDns = false;
300	log("monitor: gotmxipwrapper ip of %s for %s",
301		iptoa(ip),g_conf.m_email1MX);
302	if ( ip != 0 && ip != -1 ) {
303		// make sure ping server just uses the last legit ip
304		// if it's lookup fails
305		//g_conf.m_email1MXIPBackup = ip;
306		s_goodMXIp = ip;
307		log("monitor: saving good mxip %s",iptoa(ip));
308	}
309}
310
311
312// try to load the page every tick
313void sleepWrapper ( int fd , void *state ) {
314
315	// register ourselves
316	g_loop.unregisterSleepCallback ( state , sleepWrapper );
317	// re-register
318	g_loop.registerSleepCallback ( s_wait * 1000 ,
319				       NULL ,
320				       sleepWrapper );
321
322	//fprintf(stderr,"ok\n");
323	// the main monitoring loop
324	// loop:
325	// check port 80
326	// make the request
327	char query[1024];
328	//sprintf(query,"/index.php?q=%s&usecache=0&"
329	//	"code=gbmonitor",g_queries[g_qn]);
330	sprintf(query,"/search?q=%s&usecache=0&"
331		"code=gbmonitor",g_queries[g_qn]);
332
333	//char *host = "www1.gigablast.com";
334	// we need to use port 8002 if running from titan, but on voyager2
335	// we can still use port 80
336	int16_t port = 80;
337
338	// hack for testing on titan
339	//port = 8002;
340
341	// for debugging
342	//port = 5699;
343	
344	if( g_type[g_qn]== TYPE_BUZZ) {
345		//host = "66.231.188.239";
346		port = 8000;
347		sprintf(query,"/search?q=%s&usecache=0"
348			"&pwd=natoma",g_queries[g_qn]);
349	}
350
351	if ( g_isFlurbit )
352		sprintf(query,"/NM/Albuquerque" );
353
354	if ( g_isProCog )
355		sprintf(query,"/?q=%s&nocache=1&"
356			"code=gbmonitor",g_queries[g_qn]);
357
358
359	// launch dns lookup every 30 minutes
360	int32_t now = getTimeLocal();
361	static int32_t s_lastDnsTime = 0;
362	static int32_t s_mxip1;
363	//static DnsState s_ds;
364	if ( now - s_lastDnsTime > 30*60 ) {
365		s_lastDnsTime = now;
366		// note it
367		log("dns: calling g_dns.getIp()");
368		g_conf.m_logDebugDns = true;
369		// . smtp-sl.vtext.com
370		// . this will store it in the cache to keep it on hand
371		if ( ! g_dns.getIp ( g_conf.m_email1MX  ,
372				     strlen(g_conf.m_email1MX),
373				     &s_mxip1 ,
374				     NULL,
375				     gotMXIpWrapper ,
376				     NULL,//&s_ds,
377				     80, // 30 second timeout
378				     false, // dnslookup?
379				     // if we lose our internet connection 
380				     // temporarily we do not want to cache a 
381				     // bad ip address for the cellphone's 
382				     // mx server!!!
383				     false // CACHE NOT FOUNDS? NO!!!!!!!!
384				     ) )
385			// return if it blocked
386			return;
387		// we got it without blocking
388		log("dns: got ip without blocking");
389		gotMXIpWrapper(NULL,s_mxip1);
390	}
391
392	// save this
393	int32_t old = g_qn;
394
395	int64_t startTime = gettimeofdayInMilliseconds();
396
397	bool status;
398
399	if ( g_montest ) {
400		status = false;
401		strcpy(s_errbuf,"monitor: test error");
402	}
403	// need raw=9 so robot checking doesn't cut us off
404	else 
405		status = getPage( g_host,
406			       //"www.gidfsgablast.com",
407			       g_port,
408			       //"/search?q=test&usecache=0&raw=9&"
409			       // php front-end now redirects raw=x
410			       // to feeds.gigablast.com
411			       //"/index.php?q=test&usecache=0&"
412			       //"code=gbmonitor");
413			       query );
414
415	// check all hosts
416	//for ( uint16_t port = 8000 ; port < 8032 ; port++ ) 
417	//isUp("www.gigablast.com",port,"/cgi/0.cgi?q=test&usecache=0");
418
419	time_t t = time(NULL);
420	char *s = ctime(&t);
421	s[strlen(s)-1] = '\0';
422	char buf [ 30024 ];
423
424	int64_t took = gettimeofdayInMilliseconds() - startTime;
425
426	// if ok, loop back
427	if ( status ) { 
428		if ( ! g_isFlurbit )
429			fprintf(stderr,"monitor: %s got page ok in %"INT64" ms "
430				"(%s)\n",
431				s,took,g_queries[old]);
432		else
433			fprintf(stderr,"monitor: %s got page ok in %"INT64" ms "
434				"(flurbit.com/Albuquerque/NM)\n",
435				s,took);
436		s_count = 0; 
437		//sleep ( WAIT ); 
438		//goto loop; 
439		return;
440	}
441
442	if ( strlen(s_errbuf) > 20000 ) s_errbuf[20000] = '\0';
443	// make a pretty error msg
444	sprintf ( buf , "monitor %s:%"INT32": %s %s\n" , g_host,g_port,s,s_errbuf );
445	// log to console
446	//fprintf ( stderr , buf );
447	// there might %'s in the s_errbuf so do this!!
448	fprintf ( stderr , "monitor %s:%"INT32": %s %s\n" , g_host,g_port,s,s_errbuf );
449
450	// count the error
451	s_count++;
452
453	// have we already sent an email in the last 10 mins?
454	if ( t - s_lastTime < 10*60 ) { s_count = 0; return; }
455	//sleep ( WAIT ); goto loop; }
456
457	// we need 3 errors in a row to send an email
458	if ( s_count < 3 ) return; // { sleep ( WAIT ); goto loop; }
459
460	// log to cell phone
461	//Host h;
462	//h.m_emailCode = 0;
463	//h.m_hostId = 1000;
464	log("sendEmail: sending email alert. mxip=%s",iptoa(s_goodMXIp));
465	//if ( ! g_pingServer.sendEmail ( NULL , buf ) ) // &h , buf ) )
466	g_pingServer.sendEmail ( NULL , 
467				 buf , 
468				 true ,  // sendtoAdmin? default
469				 false,  // oom? default
470				 false,  // kernelerrors? default
471				 false,  // parmchanged? default
472				 false,  // forceit? default
473				 s_goodMXIp); // mx ip address
474	//g_fqhn ) ;
475
476	//fprintf ( stderr , "sendEmail: %s\n" , s_errbuf);
477
478	// so we don't send more than 1 email every 10 minutes
479	s_lastTime = t;
480
481	// loop back
482	s_count = 0;
483	//sleep ( WAIT );
484	//goto loop;
485	if ( g_montest ) {
486		g_montest = false;
487		s_wait = WAIT;
488	}
489}
490
491// . returns false and fills in s_errbuf on error
492// . returns true if no error
493bool getPage ( char *host , uint16_t port , char *path ) {
494	// get the socket fd
495	int sd = connectSock ( host , port );
496	if ( sd < 0 ) return false;
497	SafeBuf sbuf;
498	// a tmp buf
499	char tbuf [ 1024*100+10 ];
500	tbuf[0] = '\0';
501	// send the request
502	sprintf ( tbuf , 
503		  "GET %s HTTP/1.0\r\n"
504		  "Connection: close\r\n"
505		  "Host: www.gigablast.com\r\n\r\n" , path );
506	if ( send ( sd , tbuf , strlen(tbuf) , 0 ) == -1 ) {
507		sprintf ( s_errbuf ,"send: %s" , strerror(errno) );
508		close ( sd );
509		return false;
510	}
511	// read the reply
512	int32_t nb;
513	//int32_t sum = 0;
514
515	// make it non blocking in case we don't get reply
516	int flags = fcntl ( sd , F_GETFL ) ;
517        if ( flags < 0 ) {
518		sprintf ( s_errbuf,"fcntl: (F_GETFL): %s.",strerror(errno));
519		close ( sd );
520		return false;
521        }
522	if ( fcntl ( sd, F_SETFL, flags|O_NONBLOCK|O_ASYNC ) < 0 ) {
523		sprintf ( s_errbuf ,"fcntl: %s" , strerror(errno) );
524		close ( sd );
525		return false;
526	}
527
528	// try to fix core in Mem.cpp from trying to free in thread
529	g_mem.setPid(); // s_pid = getpid();
530	// crazy?
531	if ( g_mem.getPid() == -1 ) {
532		log("monitor: bad s_pid"); char *xx=NULL;*xx=0; }
533
534	// start time
535	int32_t now = time(NULL);
536	int32_t end = now + 25; // 25 seconds to read
537 loop:
538
539	if ( (nb = read ( sd , tbuf , 1024*100 ) ) == -1 &&
540	     errno != EAGAIN ) {
541		sprintf ( s_errbuf ,"read: %s" , strerror(errno) );
542		close ( sd );
543		return false;
544	}
545	// 0 means blocked
546	if ( nb == -1 ) { 
547		now = time(NULL);
548		if ( now >= end ) {
549			errno = ETIMEDOUT;
550			sprintf ( s_errbuf ,"read: timedout after 25 seconds "
551				  "of trying to read reply"  );
552			close ( sd );
553			return false;
554		}
555		// wait for data to be there! wait 5 ms
556		usleep(5);
557		//sleep(1);
558		goto loop;
559	}
560	// copy into safebuf
561	sbuf.safeMemcpy ( tbuf , nb );
562	// keep going if we read something
563	if ( nb > 0 ) goto loop; // { sum += nb; goto loop; }
564	// add this just in case
565	sbuf.pushChar('\0');
566	//if ( sum > 1024*100 ) sum = 1024*100;
567	//if ( sum >= 0 ) buf[sum] = '\0';
568	// . must have read something, at least this for the 'test' query!!!
569	// . no results page is only 
570	if ( sbuf.length() < 3*1024 ) {
571		sprintf ( s_errbuf ,"read: only read %"INT32" bytes for %s. "
572			  "readbuf=%s" , sbuf.length()-1, 
573			  g_queries[g_qn],
574			  sbuf.getBufStart());
575		close ( sd );
576		return false;
577	}	
578
579	// if flurbit. look for "Next " link
580	if ( g_isFlurbit && ! strstr(sbuf.getBufStart(),"Next 25") ) {
581		sprintf ( s_errbuf ,"monitor: did not read Next 25 link: "
582			  "readbuf=%s", sbuf.getBufStart());
583		close ( sd );
584		return false;
585		
586	}
587
588	// search for testpreview.com, test.com, toefl.org tmworld.com,...
589	// in the search results, at least one should be there!
590	char *p = NULL;
591	// it must contain at least one substring
592	for ( int32_t i = 0 ; i < MAX_SUBSTRINGS && ! g_isFlurbit ; i++ ) {
593		// end of list...
594		if ( g_substrings[g_qn][i] == NULL ) break;
595		p = strstr(sbuf.getBufStart(), g_substrings[g_qn][i]);
596		if ( p ) break;
597	}
598	//if ( ! p ) p = strstr(buf,"testpreview.com");
599	//if ( ! p ) p = strstr(buf,"test.com");
600	//if ( ! p ) p = strstr(buf,"toefl.org");
601	//if ( ! p ) p = strstr(buf,"tmworld.com");
602	//if ( ! p ) p = strstr(buf,"collegeboard.com");
603	//if ( ! p ) p = strstr(buf,"en.wikipedia.org");
604
605	// debug it!
606	//p = NULL;
607
608	if ( ! p && ! g_isFlurbit ) { // && !s_buzz) {
609		int32_t slen = sbuf.length();
610		char *pbuf = sbuf.getBufStart();
611		//if ( slen > 30000 ) pbuf[30000] = '\0';
612		if ( slen > 1000 ) pbuf[1000] = '\0';
613		snprintf(s_errbuf,45000,
614			 "read: bad search results (len=%"INT32") for %s "
615			"readbuf="
616			 //"????"
617			 "%s"
618			 ,sbuf.length()-1
619			 ,g_queries[g_qn]
620			 ,pbuf 
621			 );
622		close ( sd );
623		// do NOT inc g_qn cuz this query needs to work! the
624		// problem might be with just it and we need to
625		// strike out 3 times to send an email alert
626		return false;
627	}
628	
629	// try next
630	g_qn++;
631	// wrap around
632	if ( g_queries[g_qn] == NULL ) g_qn = 0;
633	
634	close ( sd );
635	// success
636	return true;
637}
638
639// . returns -1 and fill s_errbuf on error
640// . returns fd on success
641int connectSock ( char *host , uint16_t port ) {
642
643	/*
644	// use the same socket connection
645	sethostent( 0 ) ; // stayopen? 0--> use udp
646	// say what we're monitoring
647	hostent *e = gethostbyname( host );
648	// close the connection, but not for buzz because they go by ip
649	//if(!s_buzz) endhostent ();
650	endhostent ();
651	// return false on error
652	if ( ! e ) {
653		sprintf ( s_errbuf ,"connectSock: gethostbyname (%s): %s", 
654			  host, hstrerror(h_errno) );
655		return -1;
656	}
657	// get first ip address
658	//int32_t n = e->h_length;
659	uint32_t ip = *(int32_t *)(e->h_addr_list[0]);
660	*/
661	pid_t pid = getpid();
662	char cmd[256];
663	sprintf(cmd,"/usr/bin/dig +int16_t  %s | tail -1 > /tmp/ip.%"UINT32"",
664		host,(int32_t)pid);
665	system ( cmd );
666	char filename[256];
667	sprintf(filename,"/tmp/ip.%"UINT32"",(int32_t)pid);
668	FILE *fd = fopen( filename,"r");
669	char ipstring[256];
670	fscanf(fd,"%s",ipstring);
671	int32_t ip = atoip(ipstring,strlen(ipstring));
672	fclose(fd);
673
674	// print that
675	//fprintf(stderr,"ip=%s",iptoa(ip));
676
677	// now make a new socket descriptor
678	int sd = socket ( AF_INET , SOCK_STREAM , 0 ) ;
679	if ( sd < 0 ) {
680		sprintf ( s_errbuf ,"connectSock: socket: %s" , 
681			  strerror(errno) );
682		return -1;
683	}
684
685	//fd_set set;
686	//FD_ZERO(&set);
687	//FD_SET(sd,&set);
688	fcntl ( sd, F_SETFL, O_NONBLOCK );
689
690	// set up for connection
691	struct sockaddr_in to;
692	to.sin_family = AF_INET;
693	// our ip's are always in network order, but ports are in host order
694	to.sin_addr.s_addr =  ip;
695	to.sin_port        = htons (port);
696	bzero ( &(to.sin_zero) , 8 );
697
698	int64_t start = gettimeofdayInMillisecondsLocal();
699
700 connectLoop:
701	// NON-BLOCKING!
702	// connect to the socket, it returns 0 on success
703	int ret = connect ( sd, (sockaddr *)&to, sizeof(to) ) ;
704
705	if ( ret != 0 && errno != EINPROGRESS ) {
706		sprintf ( s_errbuf ,"connectSock: connect: %s" , 
707			  strerror(errno) );
708		close ( sd );
709		return -1;
710	}
711
712	// if it has been 10 seconds, forget it!
713	int64_t now = gettimeofdayInMillisecondsLocal();
714	int64_t elapsed = now - start;
715	if ( elapsed >= 10000 ) {
716		sprintf ( s_errbuf ,"connectSock: connect: TIMEDOUT!", 
717			  strerror(errno) );
718		close ( sd );
719		return -1;
720	}
721
722	// sleep for 10ms and try again
723	usleep(10);
724	goto connectLoop;
725
726	// fake return for compiler
727	return 1;
728}
729
730