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

Andreas Schneider asn at samba.org
Fri Apr 29 13:49:44 UTC 2016


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/
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 till then.


Cheers,


	-- andreas

-- 
Andreas Schneider                   GPG-ID: CC014E3D
Samba Team                             asn at samba.org
www.samba.org



More information about the samba-technical mailing list