@@ -28,7 +28,7 @@ extern struct dns_config *g_dns_cfg;
2828extern void domain_store_zones_check_create (struct kdns * kdns , char * zones );
2929
3030int tcp_domian_databd_update (struct domin_info_update * update );
31- static int dns_handle_tcp_remote (int respond_sock , char * snd_pkt , uint16_t old_id , int snd_len , char * domain );
31+ static int dns_handle_tcp_remote (int respond_sock , char * snd_pkt , uint16_t old_id , int snd_len , char * domain , struct sockaddr_in * pin );
3232
3333
3434
@@ -106,41 +106,66 @@ static int dns_do_remote_tcp_query(char *snd_buf, ssize_t snd_len, char *rvc_buf
106106}
107107
108108
109- static int dns_handle_tcp_remote (int respond_sock , char * snd_pkt ,uint16_t old_id ,int snd_len ,char * domain ) {
109+ static int dns_handle_tcp_remote (int respond_sock , char * snd_pkt ,uint16_t old_id ,int snd_len ,char * domain , struct sockaddr_in * pin ) {
110110 int i = 0 ;
111111 int retfwd = 0 ;
112- char recv_buf [16384 ] = {0 };
112+ char recv_buf [TCP_MAX_MESSAGE_LEN ] = {0 };
113113 tcp_stats .dns_fwd_rcv ++ ;
114114 domain_fwd_addrs * fwd_addrs = find_zone_fwd_addrs (domain );
115115 for (;i < fwd_addrs -> servers_len ; i ++ ){
116- retfwd = dns_do_remote_tcp_query (snd_pkt , snd_len , recv_buf , 16384 , & fwd_addrs -> server_addrs [i ]);
117- if (retfwd > 0 ) {
118- break ;
119- } else {
120- log_msg (LOG_ERR , "Failed to requset %s form %s:%d, trycnt:%d\n" , domain ,
121- inet_ntoa (((struct sockaddr_in * )fwd_addrs -> server_addrs [i ].addr )-> sin_addr ),
122- ntohs (((struct sockaddr_in * )fwd_addrs -> server_addrs [i ].addr )-> sin_port ), i );
123- }
116+ retfwd = dns_do_remote_tcp_query (snd_pkt , snd_len , recv_buf , TCP_MAX_MESSAGE_LEN , & fwd_addrs -> server_addrs [i ]);
117+ if (retfwd > 0 ) {
118+ break ;
119+ } else {
120+ char ip_src_str [INET_ADDRSTRLEN ] = {0 };
121+ char ip_dst_str [INET_ADDRSTRLEN ] = {0 };
122+ inet_ntop (AF_INET , & pin -> sin_addr , ip_src_str , sizeof (ip_src_str ));
123+ inet_ntop (AF_INET , & ((struct sockaddr_in * )fwd_addrs -> server_addrs [i ].addr )-> sin_addr , ip_dst_str , sizeof (ip_dst_str ));
124+ log_msg (LOG_ERR , "Failed to requset %s to %s:%d, from: %s, trycnt:%d\n" , domain ,
125+ ip_dst_str , ntohs (((struct sockaddr_in * )fwd_addrs -> server_addrs [i ].addr )-> sin_port ),
126+ ip_src_str , i );
127+ }
124128 }
125129 if (retfwd > 0 ){
126- uint16_t len = htons (retfwd );
127- memcpy (recv_buf , & len , 2 );
128- if (send (respond_sock ,recv_buf ,retfwd + 2 ,0 ) == -1 ){
129- log_msg (LOG_ERR ,"last send error %s\n" , domain );
130- return -1 ;
131- }
132- tcp_stats .dns_fwd_snd ++ ;
130+ uint16_t len = htons (retfwd );
131+ memcpy (recv_buf , & len , 2 );
132+ if (send (respond_sock ,recv_buf ,retfwd + 2 ,0 ) == -1 ){
133+ log_msg (LOG_ERR ,"last send error %s\n" , domain );
134+ return -1 ;
135+ }
136+ tcp_stats .dns_fwd_snd ++ ;
133137 }
134138 return 0 ;
135139}
136140
141+ static int dns_tcp_recv (int fd , char * buf , int len ) {
142+ int bytes_transmitted = 0 ;
143+ while (bytes_transmitted < len ) {
144+ int recv_len = recv (fd , buf + bytes_transmitted , len - bytes_transmitted , 0 );
145+ if (recv_len == -1 ) {
146+ if (errno == EAGAIN || errno == EINTR ) {
147+ continue ;
148+ } else {
149+ log_msg (LOG_ERR , "call recv len %d error, ret=%d, errno=%d, errinfo=%s\n" ,
150+ len , recv_len , errno , strerror (errno ));
151+ return -1 ;
152+ }
153+ } else if (recv_len == 0 ) {
154+ /* EOF */
155+ return 0 ;
156+ }
157+
158+ bytes_transmitted += recv_len ;
159+ }
160+ return bytes_transmitted ;
161+ }
137162
138163static void * dns_tcp_process (void * arg ) {
139164
140165 struct sockaddr_in sin ,pin ;
141166 char * ip = (char * )arg ;
142167 int sock_descriptor ,temp_sock_descriptor ,address_size ;
143- char buf [16384 ];
168+ char buf [TCP_MAX_MESSAGE_LEN ] = { 0 };
144169
145170 query_tcp = query_create ();
146171
@@ -151,46 +176,66 @@ static void *dns_tcp_process(void *arg) {
151176 sin .sin_family = AF_INET ;
152177 sin .sin_addr .s_addr = inet_addr (ip );;
153178 sin .sin_port = htons (53 );
154- if (bind (sock_descriptor ,(struct sockaddr * )& sin ,sizeof (sin )) == -1 )
155- {
179+ if (bind (sock_descriptor ,(struct sockaddr * )& sin ,sizeof (sin )) == -1 ) {
156180 log_msg (LOG_ERR ,"call bind err \n" );
157181 exit (1 );
158182 }
159- if (listen (sock_descriptor ,100 ) == -1 )
160- {
183+ if (listen (sock_descriptor ,100 ) == -1 ) {
161184 log_msg (LOG_ERR ,"call listen err \n" );
162185 exit (1 );
163186 }
164187 printf ("Accpting connections...\n" );
165188
166- while (1 )
167- {
168- address_size = sizeof (pin );
169- temp_sock_descriptor = accept (sock_descriptor ,(struct sockaddr * )& pin ,& address_size );
170- if (temp_sock_descriptor == -1 )
171- {
172- log_msg (LOG_ERR ,"call accept error\n" );
173- continue ;
174- }
175- int recv_len = recv (temp_sock_descriptor ,buf ,16384 ,0 );
176- if (recv_len <= 0 )
177- {
178- log_msg (LOG_ERR , "call recv error, ret=%d, errno=%d, errinfo=%s\n" , recv_len , errno , strerror (errno ));
179- close (temp_sock_descriptor );
180- continue ;
181- }
182- inet_ntop (AF_INET ,& pin .sin_addr ,host_name ,sizeof (host_name ));
183- // printf("received from client(%s):%d\n",host_name,recv_len);
189+ while (1 ) {
190+ address_size = sizeof (pin );
191+ temp_sock_descriptor = accept (sock_descriptor , (struct sockaddr * )& pin , & address_size );
192+ if (temp_sock_descriptor == -1 ) {
193+ log_msg (LOG_ERR ,"call accept error\n" );
194+ continue ;
195+ }
196+ while (1 ) {
197+ int bytes_transmitted = 0 ;
198+ bytes_transmitted = dns_tcp_recv (temp_sock_descriptor , buf , 2 ); //recv query len first
199+ if (bytes_transmitted != 2 ) {
200+ if (bytes_transmitted < 0 ) {
201+ log_msg (LOG_ERR , "failed recv len %d from %s\n" , 2 , inet_ntoa (pin .sin_addr ));
202+ }
203+ close (temp_sock_descriptor );
204+ break ;
205+ }
206+
207+ /*
208+ * Minimum query size is:
209+ *
210+ * Size of the header (12)
211+ * + Root domain name (1)
212+ * + Query class (2)
213+ * + Query type (2)
214+ */
215+ uint16_t tcp_query_len = ntohs (* (uint16_t * )buf );
216+ if (tcp_query_len < DNS_HEAD_SIZE + 1 + sizeof (uint16_t ) + sizeof (uint16_t ) || tcp_query_len > TCP_MAX_MESSAGE_LEN ) {
217+ log_msg (LOG_ERR , "tcp query from %s packet size %d illegal, drop\n" , inet_ntoa (pin .sin_addr ), tcp_query_len );
218+ close (temp_sock_descriptor );
219+ break ;
220+ }
221+
222+ bytes_transmitted = dns_tcp_recv (temp_sock_descriptor , buf + 2 , tcp_query_len );
223+ if (bytes_transmitted != tcp_query_len ) {
224+ if (bytes_transmitted < 0 ) {
225+ log_msg (LOG_ERR , "failed recv len %d from %s\n" , tcp_query_len , inet_ntoa (pin .sin_addr ));
226+ }
227+ close (temp_sock_descriptor );
228+ break ;
229+ }
184230
185231 query_reset (query_tcp );
186232 query_tcp -> maxMsgLen = TCP_MAX_MESSAGE_LEN ;
187-
188- query_tcp -> packet -> data = (uint8_t * )(buf + 2 ); // skip len
233+ query_tcp -> packet -> data = (uint8_t * )(buf + 2 ); //skip len
189234
190235 uint16_t flags_old ;
191- memcpy (& flags_old ,query_tcp -> packet -> data + 2 , 2 );
236+ memcpy (& flags_old , query_tcp -> packet -> data + 2 , 2 );
192237
193- query_tcp -> packet -> position += recv_len ;
238+ query_tcp -> packet -> position += 2 + tcp_query_len ;
194239 buffer_flip (query_tcp -> packet );
195240
196241 query_tcp -> sip = * (uint32_t * )& pin .sin_addr ;
@@ -200,28 +245,26 @@ static void *dns_tcp_process(void *arg) {
200245 buffer_flip (query_tcp -> packet );
201246 }
202247
203- if (GET_RCODE (query_tcp -> packet ) == RCODE_REFUSE ) {
204- memcpy ((buf + 2 ) + 2 , & flags_old , 2 );
205- dns_handle_tcp_remote (temp_sock_descriptor ,buf ,GET_ID (query_tcp -> packet ),recv_len ,(char * )domain_name_to_string (query_tcp -> qname , NULL ));
206- close (temp_sock_descriptor );
207- continue ;
248+ if (GET_RCODE (query_tcp -> packet ) == RCODE_REFUSE ) {
249+ memcpy ((buf + 2 ) + 2 , & flags_old , 2 );
250+ dns_handle_tcp_remote (temp_sock_descriptor , buf , GET_ID (query_tcp -> packet ), 2 + tcp_query_len , (char * )domain_name_to_string (query_tcp -> qname , NULL ), & pin );
251+ continue ;
208252 }
209253
210254 tcp_stats .dns_pkts_rcv ++ ;
211- int retLen = buffer_remaining (query_tcp -> packet );
212- if (retLen > 0 ) {
213- uint16_t len = htons (retLen );
214- memcpy (buf ,& len ,2 );
215- if (send (temp_sock_descriptor ,buf ,retLen + 2 , 0 ) == -1 ){
216- log_msg (LOG_ERR ," send error\n" );
217- }
218-
255+ int retLen = buffer_remaining (query_tcp -> packet );
256+ if (retLen > 0 ) {
257+ uint16_t len = htons (retLen );
258+ memcpy (buf , & len , 2 );
259+ if (send (temp_sock_descriptor , buf , retLen + 2 , 0 ) == -1 ) {
260+ log_msg (LOG_ERR ,"response query %s to %s, send error, errno=%d, errinfo=%s \n" ,
261+ ( char * ) domain_name_to_string ( query_tcp -> qname , NULL ), inet_ntoa ( pin . sin_addr ), errno , strerror ( errno ));
262+ }
219263 tcp_stats .dns_pkts_snd ++ ;
220- }
221-
222- close (temp_sock_descriptor );
223- }
224- }
264+ }
265+ }
266+ }
267+ }
225268
226269int dns_tcp_process_init (char * ip ){
227270 memset (& kdns_tcp ,0 ,sizeof (kdns_tcp ));
0 commit comments