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