diff --git a/src/dns_client.c b/src/dns_client.c index 2827468..376529b 100644 --- a/src/dns_client.c +++ b/src/dns_client.c @@ -447,7 +447,10 @@ int dns_server_num(void) void _dns_client_query_get(struct dns_query_struct *query) { - atomic_inc(&query->refcnt); + if (atomic_inc_return(&query->refcnt) <= 0) { + tlog(TLOG_ERROR, "BUG:query ref is invalid, domain: %s", query->domain); + abort(); + } } void _dns_client_query_release(struct dns_query_struct *query) diff --git a/src/dns_server.c b/src/dns_server.c index 370b61d..4fc31ab 100644 --- a/src/dns_server.c +++ b/src/dns_server.c @@ -170,7 +170,7 @@ static tlog_log *dns_audit; static int _dns_server_forward_request(unsigned char *inpacket, int inpacket_len) { - tlog(TLOG_ERROR, "forward request.\n"); + tlog(TLOG_DEBUG, "forward request.\n"); return -1; } @@ -284,7 +284,7 @@ static void _dns_server_client_release(struct dns_server_conn *client) if (refcnt) { if (refcnt < 0) { - tlog(TLOG_ERROR, "BUG: refcnt is %d", refcnt); + tlog(TLOG_ERROR, "BUG: refcnt is %d, type = %d", refcnt, client->type); abort(); } return; @@ -304,7 +304,11 @@ static void _dns_server_client_get(struct dns_server_conn *client) if (client == NULL) { return; } - atomic_inc(&client->refcnt); + + if (atomic_inc_return(&client->refcnt) <= 0) { + tlog(TLOG_ERROR, "BUG: client ref is invalid."); + abort(); + } } static int _dns_server_reply_tcp_to_buffer(struct dns_server_conn *client, void *packet, int len) @@ -652,7 +656,10 @@ void _dns_server_request_release(struct dns_request *request) void _dns_server_request_get(struct dns_request *request) { - atomic_inc(&request->refcnt); + if (atomic_inc_return(&request->refcnt) <= 0) { + tlog(TLOG_ERROR, "BUG: request ref is invalid, %s", request->domain); + abort(); + } } void _dns_server_ping_result(struct ping_host_struct *ping_host, const char *host, FAST_PING_RESULT result, struct sockaddr *addr, socklen_t addr_len, @@ -964,12 +971,12 @@ static int _dns_server_process_answer(struct dns_request *request, char *domain, case DNS_T_NS: { char cname[128]; dns_get_CNAME(rrs, name, 128, &ttl, cname, 128); - tlog(TLOG_DEBUG, "NS: %s %d : %s\n", name, ttl, cname); + tlog(TLOG_DEBUG, "NS: %s ttl:%d cname: %s\n", name, ttl, cname); } break; case DNS_T_CNAME: { char cname[128]; dns_get_CNAME(rrs, name, 128, &ttl, cname, 128); - tlog(TLOG_DEBUG, "%s %d : %s\n", name, ttl, cname); + tlog(TLOG_DEBUG, "name:%s ttl: %d cname: %s\n", name, ttl, cname); strncpy(request->cname, cname, DNS_MAX_CNAME_LEN); request->ttl_cname = ttl; request->has_cname = 1; @@ -1295,6 +1302,7 @@ static int _dns_server_recv(struct dns_server_conn *client, unsigned char *inpac memset(request, 0, sizeof(*request)); pthread_mutex_init(&request->ip_map_lock, 0); atomic_set(&request->adblock, 0); + atomic_set(&request->refcnt, 0); request->ping_ttl_v4 = -1; request->ping_ttl_v6 = -1; request->prefetch = 0; @@ -1367,12 +1375,20 @@ static int _dns_server_recv(struct dns_server_conn *client, unsigned char *inpac _dns_server_request_get(request); request->send_tick = get_tick_count(); - request->request_wait++; - dns_client_query(request->domain, qtype, dns_server_resolve_callback, request); if (qtype == DNS_T_AAAA && dns_conf_dualstack_ip_selection) { _dns_server_request_get(request); request->request_wait++; - dns_client_query(request->domain, DNS_T_A, dns_server_resolve_callback, request); + if (dns_client_query(request->domain, DNS_T_A, dns_server_resolve_callback, request) != 0) { + _dns_server_request_release(request); + request->request_wait--; + } + } + + request->request_wait++; + if (dns_client_query(request->domain, qtype, dns_server_resolve_callback, request) != 0) { + _dns_server_request_release(request); + _dns_server_request_remove(request); + goto errout; } return 0; @@ -1559,7 +1575,8 @@ int _dns_server_tcp_process_one_request(struct dns_server_conn *dnsserver) break; } - request_len = ntohs(*((unsigned short *)(dnsserver->recvbuff.buf + proceed_len))); + request_data = (unsigned char *)(dnsserver->recvbuff.buf + proceed_len); + request_len = ntohs(*((unsigned short *)(request_data))); if (request_len >= sizeof(dnsserver->recvbuff.buf)) { tlog(TLOG_ERROR, "request length is invalid."); diff --git a/src/fast_ping.c b/src/fast_ping.c index 636ad04..4de1853 100644 --- a/src/fast_ping.c +++ b/src/fast_ping.c @@ -44,6 +44,13 @@ #define ICMP_PACKET_SIZE (1024 * 64) #define ICMP_INPACKET_SIZE 1024 +#ifndef ICMP_FILTER +#define ICMP_FILTER 1 +struct icmp_filter { + uint32_t data; +}; +#endif + struct ping_dns_head { unsigned short id; unsigned short flag; @@ -172,7 +179,7 @@ void _fast_ping_install_filter_v6(int sock) once = 1; /* Patch bpflet for current identifier. */ - insns[1] = (struct sock_filter)BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, htons(getpid()), 0, 1); + insns[1] = (struct sock_filter)BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, htons(ping.ident), 0, 1); if (setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter))) { perror("WARNING: failed to install socket filter\n"); @@ -201,7 +208,7 @@ void _fast_ping_install_filter_v4(int sock) once = 1; /* Patch bpflet for current identifier. */ - insns[2] = (struct sock_filter)BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, htons(getpid()), 0, 1); + insns[2] = (struct sock_filter)BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, htons(ping.ident), 0, 1); if (setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter))) { perror("WARNING: failed to install socket filter\n"); @@ -259,7 +266,10 @@ errout: static void _fast_ping_host_get(struct ping_host_struct *ping_host) { - atomic_inc(&ping_host->ref); + if (atomic_inc_return(&ping_host->ref) <= 0) { + tlog(TLOG_ERROR, "BUG: ping host ref is invalid, host: %s", ping_host->host); + abort(); + } } static void _fast_ping_close_host_sock(struct ping_host_struct *ping_host) @@ -295,7 +305,7 @@ static void _fast_ping_host_put(struct ping_host_struct *ping_host) ping_host->userptr); } - tlog(TLOG_DEBUG, "ping %p end", ping_host); + tlog(TLOG_DEBUG, "ping end, id %d", ping_host->sid); // memset(ping_host, 0, sizeof(*ping_host)); ping_host->type = FAST_PING_END; free(ping_host); @@ -337,7 +347,7 @@ static int _fast_ping_sendping_v6(struct ping_host_struct *ping_host) icmp6->icmp6_type = ICMP6_ECHO_REQUEST; icmp6->icmp6_code = 0; icmp6->icmp6_cksum = 0; - icmp6->icmp6_id = getpid(); + icmp6->icmp6_id = ping.ident; icmp6->icmp6_seq = htons(ping_host->seq); gettimeofday(&packet->msg.tv, 0); @@ -562,6 +572,10 @@ static int _fast_ping_create_icmp_sock(FAST_PING_TYPE type) return -1; } + struct icmp_filter filt; + filt.data = ~((1 << ICMP_SOURCE_QUENCH) | (1 << ICMP_DEST_UNREACH) | (1 << ICMP_TIME_EXCEEDED) | (1 << ICMP_PARAMETERPROB) | (1 << ICMP_REDIRECT) | + (1 << ICMP_ECHOREPLY)); + setsockopt(fd, SOL_RAW, ICMP_FILTER, &filt, sizeof filt); setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const char *)&buffsize, optlen); setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (const char *)&buffsize, optlen); setsockopt(fd, SOL_IP, IP_TTL, &val, sizeof(val)); @@ -1420,7 +1434,7 @@ int fast_ping_init(void) pthread_mutex_init(&ping.lock, 0); hash_init(ping.addrmap); ping.epoll_fd = epollfd; - ping.ident = getpid(); + ping.ident = (getpid() & 0XFFFF); ping.run = 1; ret = pthread_create(&ping.tid, &attr, _fast_ping_work, NULL); if (ret != 0) {