[PATCH 13/13] nss_dns: Rewrite _nss_dns_gethostbyname4_r using current interfaces

Florian Weimer fweimer@redhat.com
Wed Aug 24 12:25:17 GMT 2022


* Siddhesh Poyarekar:

> On 2022-08-10 05:31, Florian Weimer via Libc-alpha wrote:
>
> Could you please add a comment on why a barrier is needed here?
>
>> +		  asm ("":::"memory");

It's a leftover from debugging.  I'll drop it in a repost.

>> @@ -1236,36 +1126,32 @@ gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2,
>>   	 is a recoverable error we now return TRYAGIN even if the first
>>   	 response was SUCCESS.  */
>>   -  if (anslen1 > 0)
>> -    status = gaih_getanswer_slice(answer1, anslen1, qname,
>> -				  &pat, &buffer, &buflen,
>> -				  errnop, h_errnop, ttlp,
>> -				  &first);
>> -
>> -  if ((status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND
>> -       || (status == NSS_STATUS_TRYAGAIN
>> -	   /* We want to look at the second answer in case of an
>> -	      NSS_STATUS_TRYAGAIN only if the error is non-recoverable, i.e.
>> -	      *h_errnop is NO_RECOVERY. If not, and if the failure was due to
>> -	      an insufficient buffer (ERANGE), then we need to drop the results
>> -	      and pass on the NSS_STATUS_TRYAGAIN to the caller so that it can
>> -	      repeat the query with a larger buffer.  */
>> -	   && (*errnop != ERANGE || *h_errnop == NO_RECOVERY)))
>> -      && answer2 != NULL && anslen2 > 0)
>> +  if (packet1len > 0)
>>       {
>> -      enum nss_status status2 = gaih_getanswer_slice(answer2, anslen2, qname,
>> -						     &pat, &buffer, &buflen,
>> -						     errnop, h_errnop, ttlp,
>> -						     &first);
>> +      status = gaih_getanswer_slice (packet1, packet1len,
>> +				     abuf, &pat, errnop, h_errnop, ttlp, true);
>> +      if (alloc_buffer_has_failed (abuf))
>> +	/* Do not try parsing the second packet if a larger result
>> +	   buffer is needed.  */
>
> NSS_STATUS_TRYAGAIN?  It does the right thing in the caller
> eventually, but this doesn't seem semantically correct.

I'm going to add more comments and switch this to NSS_STATUS_TRYAGAIN.

For one of the other functions, internal NSS_STATUS_SUCCESS is the only
case in which a resize is attempted.  See the code around line 267.

>> +	return NSS_STATUS_SUCCESS;
>> +    }
>> +
>> +  if ((status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND)
>> +      && packet2 != NULL && packet2len > 0)
>> +    {
>> +      enum nss_status status2
>> +	= gaih_getanswer_slice (packet2, packet2len,
>> +				abuf, &pat, errnop, h_errnop, ttlp,
>> +				/* Success means that data with a
>> +				   canonical name has already been
>> +				   stored.  Do not store the name again.  */
>> +				status != NSS_STATUS_SUCCESS);
>> +      if (alloc_buffer_has_failed (abuf))
>> +	/* Let the caller implement the buffer resizing protocol.  */
>> +	return NSS_STATUS_SUCCESS;
>
> Same, wouldn't NSS_STATUS_TRYAGAIN be more correct here?

I think we can remove this early return because the caller ignores the
status anyway for the buffer-exhausted case, so we do not need to
special-case it here.

I'll repost this with the barrier removed and more comments added.

Thanks,
Florian



More information about the Libc-alpha mailing list