Resolver(QObject *parent = 0) : QObject(parent), dnsA(parent), dnsB(parent) { connect(&dnsA, SIGNAL(resultsReady(const QList<XMPP::NameRecord> &)), SLOT(dns_resultsReady(const QList<XMPP::NameRecord> &))); connect(&dnsA, SIGNAL(error(XMPP::NameResolver::Error)), SLOT(dns_error(XMPP::NameResolver::Error))); connect(&dnsB, SIGNAL(resultsReady(const QList<XMPP::NameRecord> &)), SLOT(dns_resultsReady(const QList<XMPP::NameRecord> &))); connect(&dnsB, SIGNAL(error(XMPP::NameResolver::Error)), SLOT(dns_error(XMPP::NameResolver::Error))); }
static int create_fetcher(struct server *s, int n) { int i; struct fetcher *ws, *tmp; cpu_set_t cpuinfo; pthread_t fpt[FETCHER_NUM]; if (n < 1) return -1; ws = malloc(sizeof(struct fetcher) * n); //associated a worker with main thread if (ws == NULL) return -1; memset(ws, 0, sizeof(struct fetcher) * n); s->fetchers = ws; for (i = 0; i < n; i++) { tmp = ws + i; tmp->s = s; tmp->idx = i; tmp->pkg = 0; tmp->send = 0; tmp->miss = 0; tmp->el = &s->eventlist; tmp->qidx = i % QUIZZER_NUM; tmp->mc = init_msgcache(100); if (tmp->mc == NULL) dns_error(0, "get msgcache"); tmp->loginfo = malloc(sizeof(struct log_info)); memset(tmp->loginfo, 0, sizeof(struct log_info)); tmp->loginfo->lastlog = global_now; tmp->loginfo->log_type = TYPE_FETCHER; tmp->loginfo->logfd = create_new_log(s->logpath, i, TYPE_FETCHER); if (tmp->loginfo->logfd < 0) dns_error(0, "log file error"); if (pthread_create(fpt + i, NULL, (void *) run_fetcher, tmp) != 0) dns_error(0, "init worker"); } global_out_info->thread_num += i; for(i = 0;i < FETCHER_NUM ;i ++) { CPU_ZERO(&cpuinfo); CPU_SET_S(i + 1, sizeof(cpuinfo), &cpuinfo); if(0 != pthread_setaffinity_np(fpt[i], sizeof(cpu_set_t), &cpuinfo)) { printf("set affinity fetcher failed, may be the cpu cores num less than (FETCHER_NUM + QUIZZER_NUM + 1)\n"); // exit(0); } } return 0; }
/* $begin gethostbyname */ struct hostent *Gethostbyname(const char *name) { struct hostent *p; if ((p = gethostbyname(name)) == NULL) dns_error("Gethostbyname error"); return p; }
struct hostent *Gethostbyaddr(const char *addr, int len, int type) { struct hostent *p; if ((p = gethostbyaddr(addr, len, type)) == NULL) dns_error("Gethostbyaddr error"); return p; }
void init_mempool() { int ret; ret = mempool_create(MEMPOOL_SIZE); if (ret < 0) dns_error(0, "create mempool failed"); }
int init_globe() { int shmid; shmid = shmget(SHM_KEY, sizeof(struct global_query_info), IPC_CREAT|0600|IPC_PRIVATE); if (shmid < 0) { printf("%lu\n", SHM_KEY + sizeof(struct global_query_info)); perror("shmget"); dns_error(0, "shmget error"); } global_out_info = (struct global_query_info *)shmat(shmid, NULL, 0); memset(global_out_info, 0, sizeof(struct global_query_info)); global_out_info->thread_num = 0; int i; for (i = 0; i < sizeof(query_type_map) / sizeof(int); ++i) { query_type_map[i] = -1; } query_type_map[A] = 0; query_type_map[NS] = 1; query_type_map[CNAME] = 2; query_type_map[SOA] = 3; query_type_map[MX] = 4; query_type_map[TXT] = 5; query_type_map[AAAA] = 6; query_type_map[SRV] = 7; query_type_map[ANY] = 8; return 0; }
//! //! Constructs an NDns object with parent \a parent. NDns::NDns(QObject *parent) :QObject(parent),dns(this) { busy = false; connect(&dns, SIGNAL(resultsReady(QList<XMPP::NameRecord>)), SLOT(dns_resultsReady(QList<XMPP::NameRecord>))); connect(&dns, SIGNAL(error(XMPP::NameResolver::Error)), SLOT(dns_error(XMPP::NameResolver::Error))); }
//---------------rbtree debug------------------------------------// int rbtree_test(void) { int i, j, len, slice, ret; struct timeval tv; struct rbnode node, *pn = NULL; struct ttlnode *tn = NULL; struct rbtree *rbt = NULL; rbt = create_rbtree(rbt_comp_ttl_gt, NULL); if (rbt == NULL) dns_error(0, "create rbtree"); node = rbt->nil; //nil slice = 8000000; //for(i = 0;i < n;i ++) //{ for (j = 0; j < slice; j++) { len = random() % 30; tn = malloc(sizeof(struct ttlnode) + len); if (tn == NULL) printf("oom\n"); tn->exp = j; for (i = 0; i < len; i++) tn->data[i] = 'a' + i; node.key = tn; ret = insert_node(rbt, &node); if (ret != 0) printf("insert error\n"); } printf("insert all\n"); sleep(2); for (j = 0; j < slice; j++) { pn = min_node(rbt); if (pn != NULL) { tn = delete_node(rbt, pn); free(tn); } else printf("error\n"); } printf("delete all\n"); sleep(5); //} if (free_rbtree(rbt) != 0) dns_error(0, "free"); //get_time_usage(&tv,0); return 0; }
/* $begin gethostbyname_r */ int Gethostbyname_r(const char *name, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop) { int p; p = gethostbyname_r(name, ret, buf, buflen, result, h_errnop); if (p) dns_error("Gethostbyname error"); return p; }
struct hostent *Gethostbyaddr(const char *addr, int len, int type) { struct hostent *hp; hp = gethostbyaddr(addr, len, type); if (hp == NULL) { dns_error("Gethostbyaddr error"); } return hp; }
/**************************************************** *DNS interface wrappers* *****************************************************/ struct hostent *Gethostbyname(const char *hostname) { struct hostent *hp; hp = gethostbyname(hostname); if (hp == NULL) { dns_error("Gethostbyname error"); } return hp; }
static int create_listen_ports(int port, int proto, uchar * addr) { int fd = -1; fd = create_socket(port, proto, addr); if (fd < 0 || set_non_block(fd) < 0) { printf("port:%d,proto:%d\n", port, proto); dns_error(0, "fd < 0"); } return fd; }
static int daemonrize(int dm) { if (dm == 1) { if (daemon(1, 0) == -1) dns_error(0, "daemonrize"); else printf("daemon!!!\n"); //we will never see this } return 0; }
/****************************************** * Wrappers for the client/server helper routines ******************************************/ int Open_clientfd(char *hostname, int port) { int rc; if ((rc = open_clientfd(hostname, port)) < 0) { if (rc == -1) unix_error("Open_clientfd Unix error"); else dns_error("Open_clientfd DNS error"); } return rc; }
int Gethostbyaddr_r(const char *addr, int len, int type, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop) { int p; p = gethostbyaddr_r(addr, len, type, ret, buf, buflen, result, h_errnop); if (p) dns_error("Gethostbyaddr error"); return p; }
int storage_test(void) { struct htable *ht = NULL; pthread_t pt[THREADX]; int i; struct st_hlp sh[THREADX]; //ht = htable_create(NULL,dict_comp_str_equ,HASH_TABLE_SIZE,MULTI_HASH); if (ht == NULL) dns_error(0, "create htable error"); for (i = 0; i < THREADX; i++) { sh[i].ht = ht; sh[i].idx = i; if (pthread_create(pt + i, NULL, st_th, sh + i)) dns_error(0, "create pthread"); } for (i = 0; i < THREADX; i++) pthread_join(pt[i], NULL); sleep(2); return 0; }
/****************************************** * Wrappers for the client/server helper routines ******************************************/ int Open_clientfd(char *hostname, int port, char *origin_request_line, char *origin_host_header) { int rc; if ((rc = open_clientfd(hostname, port)) < 0) { if (rc == -1) unix_error("Open_clientfd Unix error"); else { dns_error("Open_clientfd DNS error"); fprintf(stderr, "Original Request Line: %s", origin_request_line); fprintf(stderr, "Original Host Header: %s", origin_host_header); fprintf(stderr, "Parsed Host: %s\n", hostname); fprintf(stderr, "Parsed Port: %d\n", port); fprintf(stderr, "Ok, That's fine.\n"); fprintf(stderr, "Our proxy will send customized response.\n\n"); } } return rc; }
static struct server * server_init(void) { struct server *s = malloc(sizeof(struct server)); if (s == NULL) dns_error(0, "out of memory in server_init"); s->nfetcher = FETCHER_NUM; s->nquizzer = QUIZZER_NUM; s->authors = NULL; s->fetchers = NULL; s->pkg = 0; pthread_spin_init(&s->eventlist.lock, 0); //pthread_mutex_init(&s->lock,NULL); s->eventlist.head = NULL; if ((s->ludp = create_listen_ports(SERVER_PORT, UDP, (uchar *)SRV_ADDR)) < 0) dns_error(0, "can not open udp"); set_sock_buff(s->ludp, 10); if ((s->ltcp = create_listen_ports(SERVER_PORT, TCP, (uchar *)SRV_ADDR)) < 0) dns_error(0, "can not open tcp"); s->datasets = htable_create(NULL, dict_comp_str_equ, HASH_TABLE_SIZE, MULTI_HASH); if (s->datasets == NULL) dns_error(0, "htable create"); s->forward = htable_create(NULL, dict_comp_str_equ, 1024, 1); if (s->forward == NULL) dns_error(0, "create forward"); s->qlist = htable_create(NULL, dict_comp_str_equ, QLIST_TABLE_SIZE, 1); if (s->qlist == NULL) dns_error(0, "create qlist"); s->ttlexp = create_rbtree(rbt_comp_ttl_gt, NULL); if (s->ttlexp == NULL) dns_error(0, "create ttl tree"); s->recordsindb = 0; s->refreshflag = 0; s->lastrefresh = global_now; s->is_forward = 0; return s; }
int main(int argc, char **argv) { struct server *s = NULL; pthread_t pt, ctl; int c, is_forward = 0; const char *config = SR_CONFIG_FILE; int daemon = 0; while ((c = getopt(argc,argv,"c:vhfd")) != -1) { switch(c) { case 'c': config = optarg; break; case 'h': help(argv[0]); exit(0); break; case 'f': is_forward = 1; break; case 'd': daemon = 1; break; case '?': printf("Try -h please\n"); exit(0); break; case 'v': printf("dnspod-sr 0.01\n"); exit(0); break; default: exit(0); break; } } sanity_test(0); drop_privilege("./"); daemonrize(daemon); trig_signals(1); global_now = time(NULL); //for read root.z g_nameservers[0] = g_nameservers[1] = NULL; init_globe(); init_mempool(); s = server_init(); s->is_forward = is_forward; read_config(config, (char *)s->logpath, s->forward, g_nameservers); // add default dns server 8.8.8.8, 114.114.114.114 if (g_nameservers[0] == NULL) { assert(g_nameservers[1] == NULL); g_nameservers[0] = strdup("119.29.29.29"); g_nameservers[1] = strdup("8.8.4.4"); } if (g_nameservers[1] == NULL) { if (strcmp(g_nameservers[0], "119.29.29.29") == 0) { g_nameservers[1] = strdup("8.8.4.4"); } else { g_nameservers[1] = strdup("119.29.29.29"); } } // if (create_fetcher(s, s->nfetcher) < 0) dns_error(0, "create worker"); if (create_author(s, s->nquizzer) < 0) dns_error(0, "create author"); if (pthread_create(&pt, NULL, (void *) time_cron, s) != 0) dns_error(0, "time cron error"); if (pthread_create(&ctl, NULL, (void *)recv_update, s) != 0) { dns_error(0, "recv update thread error"); } read_root(s->datasets, s->ttlexp); print_basic_debug(); global_serv = s; run_sentinel(s); return 0; }
int create_author(struct server *s, int n) { int i, j; struct author *authors = NULL; cpu_set_t cpuinfo; pthread_t apt[QUIZZER_NUM]; if (n < 1 || n > 50) dns_error(0, "quizzer bad range"); if ((authors = malloc(sizeof(struct author) * n)) == NULL) dns_error(0, "out of memory in quizzer"); memset(authors, 0, sizeof(struct author) * n); s->authors = authors; for (i = 0; i < n; i++) { authors[i].idx = i; authors[i].cudp = s->ludp; authors[i].audp = create_listen_ports(i * 1000 + 998, UDP, NULL); if (authors[i].audp < 0) dns_error(0, "auth fd error"); set_sock_buff(authors[i].audp, 1); authors[i].el = &s->eventlist; authors[i].s = s; get_random_data(authors[i].randombuffer, RANDOM_SIZE); authors[i].rndidx = 0; authors[i].dupbefore = 0; authors[i].limits = 10; authors[i].bdepfd = 0; authors[i].fwd = s->forward; authors[i].ds = s->datasets; authors[i].qnum = 0; authors[i].underattack = 0; authors[i].timex = 0; authors[i].response = 0; authors[i].tcpinuse = 0; authors[i].rdb = 0; authors[i].quizz = 0; authors[i].drop = 0; authors[i].timeout = 0; authors[i].qidx = 0; //start idx in qoutinfo list authors[i].start = QLIST_TABLE_SIZE / QUIZZER_NUM * i; if (i == (QUIZZER_NUM - 1)) authors[i].end = QLIST_TABLE_SIZE; else authors[i].end = QLIST_TABLE_SIZE / QUIZZER_NUM * (i + 1); memset(authors[i].ip, 0, IP_DATA_LEN); authors[i].loginfo = malloc(sizeof(struct log_info)); memset(authors[i].loginfo, 0, sizeof(struct log_info)); authors[i].loginfo->log_type = TYPE_QUIZZER; authors[i].loginfo->logfd = create_new_log(s->logpath, i, TYPE_QUIZZER); for (j = 0; j < AUTH_DB_NUM; j++) pthread_spin_init(&(authors[i].dblock[j]), 0); for (j = 0; j < LIST_SPACE; j++) authors[i].list[j] = NULL; for (j = 0; j < EP_TCP_FDS; j++) authors[i].eptcpfds[j].ret = -1; pthread_spin_init(&authors[i].lock, 0); authors[i].loginfo->lastlog = global_now; if (authors[i].cudp < 0 || authors[i].audp < 0) dns_error(0, "create quizzer2"); if (pthread_create(apt + i, NULL, run_quizzer, (void *) &(authors[i])) != 0) dns_error(0, "create quizzer"); } global_out_info->thread_num += i; for(i = 0;i < QUIZZER_NUM ;i ++) { CPU_ZERO(&cpuinfo); CPU_SET_S(i + FETCHER_NUM + 1, sizeof(cpuinfo), &cpuinfo); if(0 != pthread_setaffinity_np(apt[i], sizeof(cpu_set_t), &cpuinfo)) { printf("set affinity quizzer failed, may be the cpu cores num less than (FETCHER_NUM + QUIZZER_NUM + 1)\n"); // exit(0); } } return 0; }
/* puts TXT from dns response in buf. Returns length of TXT on success, -1 on fail.*/ static int parse_dns_response(ToxWindow *self, u_char *answer, int ans_len, char *buf) { uint8_t *ans_pt = answer + sizeof(HEADER); uint8_t *ans_end = answer + ans_len; char exp_ans[PACKETSZ]; int len = dn_expand(answer, ans_end, ans_pt, exp_ans, sizeof(exp_ans)); if (len == -1) return dns_error(self, "dn_expand failed."); ans_pt += len; if (ans_pt > ans_end - 4) return dns_error(self, "DNS reply was too short."); int type; GETSHORT(type, ans_pt); if (type != T_TXT) return dns_error(self, "Broken DNS reply."); ans_pt += INT16SZ; /* class */ uint32_t size = 0; /* recurse through CNAME rr's */ do { ans_pt += size; len = dn_expand(answer, ans_end, ans_pt, exp_ans, sizeof(exp_ans)); if (len == -1) return dns_error(self, "Second dn_expand failed."); ans_pt += len; if (ans_pt > ans_end - 10) return dns_error(self, "DNS reply was too short."); GETSHORT(type, ans_pt); ans_pt += INT16SZ; ans_pt += 4; GETSHORT(size, ans_pt); if (ans_pt + size < answer || ans_pt + size > ans_end) return dns_error(self, "RR overflow."); } while (type == T_CNAME); if (type != T_TXT) return dns_error(self, "DNS response failed."); uint32_t txt_len = *ans_pt; if (!size || txt_len >= size || !txt_len) return dns_error(self, "No record found."); if (txt_len > MAX_DNS_REQST_SIZE) return dns_error(self, "Invalid DNS response."); ans_pt++; ans_pt[txt_len] = '\0'; memcpy(buf, ans_pt, txt_len + 1); return txt_len; }
/* Does DNS lookup for addr and puts resulting tox id in id_bin. */ void *dns3_lookup_thread(void *data) { ToxWindow *self = t_data.self; char inputdomain[MAX_STR_SIZE]; char name[MAX_STR_SIZE]; int namelen = parse_addr(t_data.addr, name, inputdomain); if (namelen == -1) { dns_error(self, "Must be a Tox ID or an address in the form username@domain"); killdns_thread(NULL); } char DNS_pubkey[DNS3_KEY_SIZE]; char domain[MAX_DOMAIN_SIZE]; int match = get_domain_match(DNS_pubkey, domain, inputdomain); if (match == -1) { dns_error(self, "Domain not found."); killdns_thread(NULL); } void *dns_obj = tox_dns3_new((uint8_t *) DNS_pubkey); if (dns_obj == NULL) { dns_error(self, "Core failed to create DNS object."); killdns_thread(NULL); } char string[MAX_DNS_REQST_SIZE + 1]; uint32_t request_id; int str_len = tox_generate_dns3_string(dns_obj, (uint8_t *) string, sizeof(string), &request_id, (uint8_t *) name, namelen); if (str_len == -1) { dns_error(self, "Core failed to generate DNS3 string."); killdns_thread(dns_obj); } string[str_len] = '\0'; u_char answer[PACKETSZ]; char d_string[MAX_DOMAIN_SIZE + MAX_DNS_REQST_SIZE + 10]; /* format string and create dns query */ snprintf(d_string, sizeof(d_string), "_%s._tox.%s", string, domain); int ans_len = res_query(d_string, C_IN, T_TXT, answer, sizeof(answer)); if (ans_len <= 0) { dns_error(self, "DNS query failed."); killdns_thread(dns_obj); } char ans_id[MAX_DNS_REQST_SIZE + 1]; /* extract TXT from DNS response */ if (parse_dns_response(self, answer, ans_len, ans_id) == -1) killdns_thread(dns_obj); char encrypted_id[MAX_DNS_REQST_SIZE + 1]; int prfx_len = strlen(TOX_DNS3_TXT_PREFIX); /* extract the encrypted ID from TXT response */ if (strncmp(ans_id, TOX_DNS3_TXT_PREFIX, prfx_len) != 0) { dns_error(self, "Bad DNS3 TXT response."); killdns_thread(dns_obj); } memcpy(encrypted_id, ans_id + prfx_len, ans_len - prfx_len); if (tox_decrypt_dns3_TXT(dns_obj, (uint8_t *) t_data.id_bin, (uint8_t *) encrypted_id, strlen(encrypted_id), request_id) == -1) { dns_error(self, "Core failed to decrypt DNS response."); killdns_thread(dns_obj); } pthread_mutex_lock(&Winthread.lock); cmd_add_helper(self, t_data.m, t_data.id_bin, t_data.msg); pthread_mutex_unlock(&Winthread.lock); killdns_thread(dns_obj); return 0; }