net ads dns gethostbyname seems to fail in the self-test environment

Richard Sharpe realrichardsharpe at gmail.com
Mon May 9 05:09:57 UTC 2016


On Fri, Apr 29, 2016 at 6:49 AM, Andreas Schneider <asn at samba.org> wrote:
> On Thursday, 28 April 2016 08:36:27 CEST Richard Sharpe wrote:
>> Hi folks,
>>
>> I am seeing net ads dns gethostbyname <server> <name> fail in the
>> selftest environment.
>>
>> That code does:
>>
>> DNS_ERROR do_gethostbyname(const char *server, const char *host)
>> {
>>         struct dns_connection *conn = NULL;
>>         struct dns_request *req, *resp;
>>         DNS_ERROR err;
>>
>>         err = dns_open_connection(server, DNS_UDP, NULL, &conn);
>>         if (!ERR_DNS_IS_OK(err)) goto error;
>>
>>         err = dns_create_query(conn, host, QTYPE_A, DNS_CLASS_IN, &req);
>>         if (!ERR_DNS_IS_OK(err)) goto error;
>>
>>         err = dns_transaction(conn, conn, req, &resp);
>>
>>  error:
>>         TALLOC_FREE(conn);
>>         return err;
>> }
>>
>> After opening the 'connection', the UDP version does this:
>>
>>         RecvAddrLen = sizeof(RecvAddr);
>>         if (getpeername(conn->s,
>>                         (struct sockaddr *)&RecvAddr,
>>                         &RecvAddrLen) == -1) {
>>                 return ERROR_DNS_CONNECTION_FAILED;
>>         }
>>
>>         conn->hType = DNS_UDP;
>>         memcpy(&conn->RecvAddr, &RecvAddr, sizeof(struct sockaddr_storage));
>>
>> which saves the recipient sockaddr structure.
>>
>> Then dns_transaction is called which calls dns_send which calls
>> dns_send_udp which does the following:
>>
>>         do {
>>                 ret = sendto(conn->s, buf->data, buf->offset, 0,
>>                      (struct sockaddr *)&conn->RecvAddr,
>>                      sizeof(conn->RecvAddr));
>>         } while ((ret == -1) && (errno == EINTR));
>>
>> Now, in the socket wrapper environment, if we get a sendto on a UDP
>> socket that is connected and we have a dest address, we return
>> EISCONN, which is almost correct, and causes the net ads dns
>> gethostbyname code to fail.
>>
>> What I think we should do is to compare the destination address to the
>> one passed in and if they are the same, then don't reject the request.
>> If they are different, maybe still return EISCONN.
>>
>> However, our next problem will be that sendto on a UNIX socket with a
>> dest address will also fail with EINVAL, so we need to further simply
>> not supply the dest address in that case.
>>
>> Does this sound like a reasonable analysis of what the problem is and
>> the solution?
>>
>> I would really like to create some tests for the net ads dns code so I
>> want to get this resolved.
>
> Ok, so the code does:
>
> socket()
> connect()
> sendto()
>
> and socket wrapper fails with EISCONN, because of the connect().
>
> The socket_wrapper testsuite implements a simple echo server. We need to
> implement a test and fix it.
>
> test_echo_udp_sendto_recvfrom.c is the place to implement that test.
>
> https://git.samba.org/?p=socket_wrapper.git;a=blob;f=tests/

OK, I think I have a fix for this. Now I can work on a test :-)

Along the way I found that do_gethostbyname does nothing with the
response, even though I am now getting the response in a
socket_wrapper environment, so that needs to be fixed as well.

I was planning to use the net ads dns gethostbyname command for tests ...

> test_echo_udp_sendto_recvfrom.c;h=79948ced4718668cec037a0d2efb3a72704f08ac;hb=HEAD
>
> Add a test_sendto_connect() test in that file.
>
> The tests/README show how to run the test without socket_wrapper. So you can
> implement the test and make sure it works correctly with glibc. Then you can
> run it in the testenv with socket wrapper.
>
> ctest -V -R test_echo_udp_sendto_recvfrom
>
> And start to implement a fix.
>
> I'm at the SSH Hackathon next week, so I don't have time for that. We can look
> into it at SambaXP if you do not get it fixed til then.


-- 
Regards,
Richard Sharpe
(何以解憂?唯有杜康。--曹操)



More information about the samba-technical mailing list