#include "check_neocast.h" #include "protocol.h" #include "cfgconfig.h" #include "util.h" #include #include #include extern int dig_func(int , char **, int *, int *); extern int Tcp_connect(const char *, const char *); extern void Send(int, const void *, size_t, int); extern ssize_t Recv(int, void *, size_t, int); static char hexchars[] = "0123456789ABCDEF"; void safe_wait() { struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 100; select(0, NULL, NULL, NULL, &tv); } #define STAT_STAMP(a) (((a) + (stat_term - 1)) / stat_term) void loop_check() { int ret_val = 0; int stat_term; time_t now, past; unsigned long past_stamp = 0; unsigned long now_stamp = 0; SetIniName(CFGFILE); stat_term = GetProfileInt("STAT_TERM", 60); now = past = time(NULL); now_stamp = past_stamp = STAT_STAMP(now); for( ; ; ) { now = time(NULL); now_stamp = STAT_STAMP(now); if (past != now) { // whenever 1 minutes (60 seconds) ret_val = check_neocast(now, &now_stamp, &past_stamp); if (ret_val == 1) { past = now = time(NULL); now_stamp = past_stamp = STAT_STAMP(now); } } safe_wait(); } } int check_neocast(time_t now, unsigned long *now_stamp, unsigned long *past_stamp) { FILE *shLogFile = NULL; struct tm *t; neo_serv_info *nserv_info, *temp_info; MYSQL mysql, child_mysql; MYSQL_RES *res; MYSQL_ROW row; int i; int mysql_port, fields; long numRows; long cnt = 0; char mysql_db[8]; char mysql_user[16]; char mysql_pass[16]; char logString[1024]; /* check time */ if (*now_stamp == *past_stamp) return 0; /* sh log file open */ shLogFile = fopen(makeLogString(), "a"); if (!shLogFile) { fprintf(stderr, "Cannot open SH Log file!!\n"); exit(EXIT_FAILURE); } /***********************************************************************************************************/ /* initialize mysqlDB */ mysql_init(&mysql); mysql_init(&child_mysql); // get mysql info SetIniName(CFGFILE); GetProfile("DATABASE_NAME", mysql_db, "CCDB"); GetProfile("DATABASE_ACCT", mysql_user, "root"); GetProfile("DATABASE_PW", mysql_pass, "alfkzmf!?{}"); mysql_port = GetProfileInt("DATABASE_PORT", 3306); fprintf(stderr, "DATABASE_NAME : %s\n", mysql_db); fprintf(stderr, "DATABASE_ACCT : %s\n", mysql_user); fprintf(stderr, "DATABASE_PW : %s\n", mysql_pass); fprintf(stderr, "DATABASE_PORT : %d\n", mysql_port); /* connect mysqlDB */ if (!mysql_real_connect(&mysql, NULL, mysql_user, mysql_pass, mysql_db, mysql_port, (char *)NULL, 0)) { fprintf(stderr, "parent mysql: %s\n", mysql_error(&mysql)); snprintf(logString, 1024, "%s", mysql_error(&mysql)); WriteSHLog(logString, shLogFile); exit(EXIT_FAILURE); } if (!mysql_real_connect(&child_mysql, NULL, mysql_user, mysql_pass, mysql_db, mysql_port, (char *)NULL, 0)) { fprintf(stderr, "%s\n", mysql_error(&child_mysql)); snprintf(logString, 1024, "child mysql: %s", mysql_error(&child_mysql)); WriteSHLog(logString, shLogFile); exit(EXIT_FAILURE); } /***********************************************************************************************************/ /* autocommit on */ mysql_autocommit(&child_mysql, 1); snprintf(logString, 1024, "Query to get arranged Server List :: %s", MYQUERY); WriteSHLog(logString, shLogFile); if (mysql_query(&mysql, MYQUERY) < 0) { snprintf(logString, 1024, "[error]%s", mysql_error(&mysql)); WriteSHLog(logString, shLogFile); exit(EXIT_FAILURE); } else { snprintf(logString, 1024, "%s", "[MySQL]Server List Loading Success!!"); WriteSHLog(logString, shLogFile); } res = mysql_store_result(&mysql); fields = mysql_num_fields(res); numRows = mysql_num_rows(res); snprintf(logString, 1024, "numRows --> %ld", numRows); WriteSHLog(logString, shLogFile); neo_serv_num = numRows; nserv_info = (neo_serv_info *)malloc(sizeof(neo_serv_info)); temp_info = nserv_info; while((row = mysql_fetch_row(res))) { memset(temp_info, 0, sizeof(temp_info)); temp_info->neo_seq = atol(row[0]); strncpy(temp_info->name, row[1], MaxSizeOfServerName); strncpy(temp_info->domain, row[2], MaxSizeOfServerAddr); strncpy(temp_info->dig_domain, row[3], MaxSizeOfServerAddr); strncpy(temp_info->ipaddr, row[4], MaxSizeOfServerIp); strncpy(temp_info->type ,row[5], MaxSizeOfServerType); temp_info->port = atoi(row[6]); temp_info->dead_count = atoi(row[7]); temp_info->status = atoi(row[8]); temp_info->next = NULL; temp_info->next = (neo_serv_info *)malloc(sizeof(neo_serv_info)); temp_info = temp_info->next; } temp_info = NULL; temp_info = nserv_info; for (cnt = 0; cnt < neo_serv_num; cnt++) { pid_t dpid; int status = 0; // check neocast STAT if (!strcmp(temp_info->type, "STAT")) { char buf[1024]; int result; // CHG 2010-10-21 huibong KT -> X-CDN //sprintf(buf, "wget -T 10 -t 2 -q \"http://222.122.18.6/neo_status\" -O /root/neo_status"); sprintf(buf, "wget -T 10 -t 2 -q \"http://www.x-cdn.com/neo_status\" -O /root/neo_status"); WriteSHLog(buf, shLogFile); result = system(buf); if (result == 0) { FILE *fp = NULL; char update_query[1024]; char msgStr[1024]; sprintf(buf, "/root/neo_status"); if ((fp = fopen(buf, "r"))) { memset(buf, 0, 4); fread(buf, 1, 3, fp); if (buf[0] == 'O') { // wget success WriteSHLog("[STAT SUCCESS!]", shLogFile); if (temp_info->status == 2 || temp_info->dead_count > 0) { snprintf(update_query, 1024, "UPDATE t_neo_server_index SET dead_count = 0, status = 1, update_datetime = now() WHERE neo_seq = %ld", temp_info->neo_seq); WriteSHLog(update_query, shLogFile); if (mysql_query(&child_mysql, update_query) != 0) { snprintf(logString, 1024, "[error]%s", mysql_error(&child_mysql)); WriteSHLog(logString, shLogFile); exit(EXIT_FAILURE); } else { snprintf(logString, 1024, "%s", "Update STAT query Success!!"); WriteSHLog(logString, shLogFile); } // SMS BACK and SendToWebServ if (temp_info->status == 2) { snprintf(msgStr, MaxSizeOfsmsStr, "[NEO][BACK] STAT IS BACK!"); SendToWebServ(msgStr, shLogFile); } } } else if (buf[0] == 'E') { WriteSHLog("[!STAT FAIL]", shLogFile); // SMS DEAD and SendToWebServ if (temp_info->dead_count >= MAX_ALLOWED_DEAD_COUNT && ((int)temp_info->dead_count < MAX_ALLOWED_DEAD_COUNT + 5)) { snprintf(msgStr, MaxSizeOfsmsStr, "[NEO][DEAD] STAT IS ERROR!!"); snprintf(update_query, 1024, "UPDATE t_neo_server_index SET dead_count = %d, status = 2, update_datetime = now() WHERE neo_seq = %ld", temp_info->dead_count + 1, temp_info->neo_seq); SendToWebServ(msgStr, shLogFile); } else { // SMS DEAD but not SendToWebServ snprintf(update_query, 1024, "UPDATE t_neo_server_index SET dead_count = %d, update_datetime = now() WHERE neo_seq = %ld", temp_info->dead_count + 1, temp_info->neo_seq); } WriteSHLog(update_query, shLogFile); if (mysql_query(&child_mysql, update_query) != 0) { snprintf(logString, 1024, "[error]%s", mysql_error(&child_mysql)); WriteSHLog(logString, shLogFile); exit(EXIT_FAILURE); } else { snprintf(logString, 1024, "%s", "Update STAT query Success!!"); WriteSHLog(logString, shLogFile); } } } if (fp) fclose(fp); } } signal(SIGCHLD, SIG_DFL); dpid = fork(); // child must process dig func if (dpid == 0) { int i; char dig_cmd[1024]; char update_query[1024]; char msgStr[1024]; char *paraop[512]; int qrcount = 0; int ancount = 0; int retval = 0; if (!strcmp(temp_info->type, "STAT")) { fclose(shLogFile); exit(EXIT_SUCCESS); } setproctitle("grandchildren: working for digging..."); snprintf(dig_cmd, 1024, "dig @%s %s", temp_info->domain, temp_info->dig_domain); WriteSHLog(dig_cmd, shLogFile); paraop[0] = (char *)malloc(512); paraop[1] = (char *)malloc(512); paraop[2] = (char *)malloc(512); memset(paraop[0], 0, 512); memset(paraop[1], 0, 512); memset(paraop[2], 0, 512); strncpy(paraop[0], "dig", 512); snprintf(paraop[1], 512, "@%s", temp_info->domain); strncpy(paraop[2], temp_info->dig_domain, 512); retval = dig_func(3, paraop, &qrcount, &ancount); /* three case */ /* fail : invaild dns name : retval = -1, ancount = 0 */ /*fail : invalid domain name, query timout : retval = 0, ancount = 0 */ /* success : retval = 0, ancount >= 1*/ snprintf(logString, 1024, "dig result : QUERY: %d, ANSWER: %d", qrcount, ancount); WriteSHLog(logString, shLogFile); if (retval == -1 || (qrcount == 0 && ancount == 0)) { //if (temp_info->dead_count >= MAX_ALLOWED_DEAD_COUNT && ((int)temp_info->dead_count < MAX_ALLOWED_DEAD_COUNT + 5)) { //modify sindong .... 09/12/31 if (temp_info->dead_count >= 0 && ((int)temp_info->dead_count < MAX_ALLOWED_DEAD_COUNT + 5)) { // SMS DEAD and SendToWebServ snprintf(msgStr, MaxSizeOfsmsStr, "[NEO][DEAD] %s \n", dig_cmd); snprintf(update_query, 1024, "UPDATE t_neo_server_index SET dead_count = %d, status = 2, update_datetime = now() WHERE neo_seq = %ld", temp_info->dead_count + 1, temp_info->neo_seq); SendToWebServ(msgStr, shLogFile); } else { // SMS DEAD but not SendToWebServ snprintf(update_query, 1024, "UPDATE t_neo_server_index SET dead_count = %d, update_datetime = now() WHERE neo_seq = %ld", temp_info->dead_count + 1, temp_info->neo_seq); } } else if (qrcount >= 1 && ancount >= 1) { if (temp_info->status == 2) { snprintf(update_query, 1024, "UPDATE t_neo_server_index SET dead_count = 0, status = 1, update_datetime = now() WHERE neo_seq = %ld", temp_info->neo_seq); // SMS BACK and SendToWebServ snprintf(msgStr, MaxSizeOfsmsStr, "[NEO][BACK] %s \n", dig_cmd); SendToWebServ(msgStr, shLogFile); } else if (temp_info->status == 1 && temp_info->dead_count == 0) goto free_exit; else snprintf(update_query, 1024, "UPDATE t_neo_server_index SET dead_count = 0, status = 1, update_datetime = now() WHERE neo_seq = %ld", temp_info->neo_seq); } else goto free_exit; WriteSHLog(update_query, shLogFile); if (mysql_query(&child_mysql, update_query) != 0) { snprintf(logString, 1024, "[error]%s", mysql_error(&child_mysql)); WriteSHLog(logString, shLogFile); exit(EXIT_FAILURE); } else { snprintf(logString, 1024, "%s", "Update DIG query Success!!"); WriteSHLog(logString, shLogFile); } free_exit: for (i=0; i < 3; i++) free(paraop[i]); exit(EXIT_SUCCESS); } wait(&status); temp_info = temp_info->next; usleep(1); } WriteSHLog("----------------------------------------------------- end ---------------------------------------------\n", shLogFile); *past_stamp = *now_stamp; mysql_free_result(res); mysql_close(&mysql); mysql_close(&child_mysql); fclose(shLogFile); for (i=0; i < neo_serv_num; i++) { free(nserv_info); nserv_info = nserv_info->next; } free(nserv_info); return 1; } // CHG 2010-10-20 huibong KT -> X-CDN //#define SMSServAddr "222.122.136.110" //#define SMSServerHost "sh.0x31.com" //#define SMSServPort "80" //#define MaxSizeOfTRxBuffer 1024 #define SMSServAddr "www.x-cdn.com" #define SMSServerHost "gms.x-cdn.com" #define SMSServPort "8080" #define MaxSizeOfTRxBuffer 1024 void SendToWebServ(const char *pszMesg, FILE *shLogFile) { char *PostDataEncode(const char *); char *strURI; char szSndBuffer[MaxSizeOfTRxBuffer]; char szRcvBuffer[MaxSizeOfTRxBuffer]; char logString[1024]; char sms_admin[32]; int fd, n, k, param_num; bzero(szSndBuffer, MaxSizeOfTRxBuffer); bzero(szRcvBuffer, MaxSizeOfTRxBuffer); strURI = PostDataEncode(pszMesg); SetIniName(CFGFILE); GetProfile("SMS_ADMIN", sms_admin, "ADMIN"); snprintf(szSndBuffer, MaxSizeOfTRxBuffer, "GET /sms/send_sms.html?id=%s&msg=%s HTTP/1.0\n"\ "Content-Type: text/plain\n"\ "User-Agent: SeanZilla/1.0\n"\ "Host: %s\n"\ "Connection: close\n"\ "Cache-Control: no-cache\n\n" , sms_admin, strURI, SMSServerHost); snprintf(logString, 1024, "[SMS Result]::id=%s :: msg=%s", sms_admin, pszMesg); WriteSHLog(logString, shLogFile); /* tcp connection, send, receive */ fd = Tcp_connect(SMSServAddr, SMSServPort); /* send sndMessage to SMS WEB SERV */ Send(fd, szSndBuffer, strlen(szSndBuffer), 0); usleep(1); /* receive result from new sh_statusd */ if ( (n = Recv(fd, szRcvBuffer, strlen(szRcvBuffer), 0)) == 0) { #if 0 snprintf(logString, 1024, "[SMS] server : %s", strURI); WriteSHLog(logString, shLogFile); #endif } free(strURI); close(fd); } char *PostDataEncode(const char *pszCommand) { int i = 0; char tmpBuffer[MaxSizeOfTRxBuffer]; static char *strReturn; if(pszCommand == NULL) { return NULL; } while(*pszCommand != '\0') { if(*pszCommand == ' ') { tmpBuffer[i++] = '+'; *pszCommand++; } else if((*pszCommand < '0' && *pszCommand != '-' && *pszCommand != '.' && *pszCommand !='%') || (*pszCommand < 'A' && *pszCommand > '9' && *pszCommand !='%') || (*pszCommand > 'Z' && *pszCommand < 'a' && *pszCommand != '_' && *pszCommand !='%') || (*pszCommand > 'z' && *pszCommand !='%')) { tmpBuffer[i++] = '%'; tmpBuffer[i++] = hexchars[(unsigned char)*pszCommand >> 4]; tmpBuffer[i++] = hexchars[(unsigned char)*pszCommand & 15]; *pszCommand++; } else if(*pszCommand == '%') { tmpBuffer[i++] = '%'; tmpBuffer[i++] = '%'; *pszCommand++; } else { tmpBuffer[i++] = *pszCommand++; } } tmpBuffer[i] = '\0'; // allocate heap strReturn = (char *)malloc(strlen(tmpBuffer)); memset(strReturn, 0, strlen(tmpBuffer)); strncpy(strReturn, tmpBuffer, strlen(tmpBuffer)+1); return strReturn; }