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