| 
					
				 | 
			
			
				@@ -142,13 +142,37 @@ void MockServer::Run() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			head.aa = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			head.rd = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			head.ra = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			head.rcode = DNS_RC_SERVFAIL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			head.rcode = DNS_RC_NOERROR; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			dns_packet_init(request.response_packet, sizeof(response_packet_buff), &head); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			auto callback_ret = callback_(&request); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			if (callback_ret == false || request.response_data_len == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if (callback_ret == SERVER_REQUEST_ERROR) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				dns_packet_init(request.response_packet, sizeof(response_packet_buff), &head); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				request.response_packet->head.rcode = DNS_RC_SERVFAIL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				dns_add_domain(request.response_packet, request.domain.c_str(), request.qtype, request.qclass); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				request.response_data_len = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					dns_encode(request.response_data, request.response_data_max_len, request.response_packet); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} else if (request.response_data_len == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				if (callback_ret == SERVER_REQUEST_OK) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					request.response_data_len = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						dns_encode(request.response_data, request.response_data_max_len, request.response_packet); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} else if (callback_ret == SERVER_REQUEST_SOA) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					struct dns_soa soa; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					memset(&soa, 0, sizeof(soa)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					strncpy(soa.mname, "ns1.example.com", sizeof(soa.mname)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					strncpy(soa.rname, "hostmaster.example.com", sizeof(soa.rname)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					soa.serial = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					soa.refresh = 3600; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					soa.retry = 600; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					soa.expire = 86400; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					soa.minimum = 3600; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					dns_packet_init(request.response_packet, sizeof(response_packet_buff), &head); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					dns_add_domain(request.response_packet, request.domain.c_str(), request.qtype, request.qclass); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					request.response_packet->head.rcode = DNS_RC_NXDOMAIN; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					dns_add_SOA(request.response_packet, DNS_RRS_AN, request.domain.c_str(), 1, &soa); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					request.response_data_len = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						dns_encode(request.response_data, request.response_data_max_len, request.response_packet); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			sendto(fd_, request.response_data, request.response_data_len, MSG_NOSIGNAL, (struct sockaddr *)&from, 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -157,6 +181,33 @@ void MockServer::Run() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+bool MockServer::AddIP(struct ServerRequestContext *request, const std::string &domain, const std::string &ip, int ttl) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct sockaddr_storage addr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	socklen_t addrlen = sizeof(addr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	memset(&addr, 0, sizeof(addr)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (GetAddr(ip, "53", SOCK_DGRAM, IPPROTO_UDP, &addr, &addrlen)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (addr.ss_family == AF_INET) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			dns_add_A(request->response_packet, DNS_RRS_AN, domain.c_str(), ttl, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					  (unsigned char *)&addr4->sin_addr.s_addr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} else if (addr.ss_family == AF_INET6) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				dns_add_A(request->response_packet, DNS_RRS_AN, domain.c_str(), ttl, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						  (unsigned char *)&addr6->sin6_addr.s6_addr[12]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			dns_add_AAAA(request->response_packet, DNS_RRS_AN, domain.c_str(), ttl, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						 (unsigned char *)&addr6->sin6_addr.s6_addr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 bool MockServer::GetAddr(const std::string &host, const std::string port, int type, int protocol, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						 struct sockaddr_storage *addr, socklen_t *addrlen) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 |