context.c revision a4987cc03171e0ff3e3b07e7aac0f6bde8e09bf2
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews/*
28d9fd53819cc163629c867466b20d8ebcae8842David Lawrence * Copyright (C) 2000 Internet Software Consortium.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * Permission to use, copy, modify, and distribute this software for any
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * purpose with or without fee is hereby granted, provided that the above
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * copyright notice and this permission notice appear in all copies.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
15a44745412679c30a6d022733925af70a38b715David Lawrence * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
15a44745412679c30a6d022733925af70a38b715David Lawrence * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
15a44745412679c30a6d022733925af70a38b715David Lawrence * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
15a44745412679c30a6d022733925af70a38b715David Lawrence * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
15a44745412679c30a6d022733925af70a38b715David Lawrence * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15a44745412679c30a6d022733925af70a38b715David Lawrence * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
15a44745412679c30a6d022733925af70a38b715David Lawrence * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
15a44745412679c30a6d022733925af70a38b715David Lawrence * SOFTWARE.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews */
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
228c679d7a269423019f7c528db92e855f08240bMark Andrews#include <config.h>
0c310d16b05ee94743d33f6920907edee6084fc8Michael Graff
0c310d16b05ee94743d33f6920907edee6084fc8Michael Graff#include <assert.h>
de153390f5a1f6d4fa86af91d4cae772d9846ca0Mark Andrews#include <fcntl.h>
0c310d16b05ee94743d33f6920907edee6084fc8Michael Graff#include <stdlib.h>
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington#include <string.h>
ebfcb6cf66283096ebda1503b6cc042ce86b6bedBrian Wellington#include <unistd.h>
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <sys/types.h>
25a66b4e41e2b0a2af4840749bac80ae78c678bfMark Andrews#include <sys/time.h>
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence#include <sys/socket.h>
973a19342597823f111fce6a8cd5adfd0e2e7c0dMark Andrews
0c310d16b05ee94743d33f6920907edee6084fc8Michael Graff#include <netinet/in.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <lwres/context.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <lwres/lwres.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <lwres/result.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#include "context_p.h"
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews#include "assert_p.h"
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrewsstatic void *lwres_malloc(void *, size_t);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencestatic void lwres_free(void *, void *, size_t);
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrewsstatic int context_connect(lwres_context_t *);
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssonint
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssonlwres_context_create(lwres_context_t **contextp, void *arg,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews lwres_malloc_t malloc_function,
eb6bd543c7d072efdca509eb17f8f301c1467b53Mark Andrews lwres_free_t free_function)
600cfa2ba4c50017581b6c14e3a688a82ecebbe0David Lawrence{
600cfa2ba4c50017581b6c14e3a688a82ecebbe0David Lawrence lwres_context_t *ctx;
600cfa2ba4c50017581b6c14e3a688a82ecebbe0David Lawrence
eb6bd543c7d072efdca509eb17f8f301c1467b53Mark Andrews REQUIRE(contextp != NULL && *contextp == NULL);
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrews
0b056755b2f423ba5f6adac8f7851d78f7d11437David Lawrence /*
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence * If we were not given anything special to use, use our own
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence * functions. These are just wrappers around malloc() and free().
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence */
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence if (malloc_function == NULL || free_function == NULL) {
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence REQUIRE(malloc_function == NULL);
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence REQUIRE(free_function == NULL);
0b056755b2f423ba5f6adac8f7851d78f7d11437David Lawrence malloc_function = lwres_malloc;
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence free_function = lwres_free;
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence }
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence ctx = malloc_function(arg, sizeof(lwres_context_t));
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence if (ctx == NULL)
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence return (LWRES_R_NOMEMORY);
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence /*
0b056755b2f423ba5f6adac8f7851d78f7d11437David Lawrence * Set up the context.
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence */
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence ctx->malloc = malloc_function;
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence ctx->free = free_function;
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence ctx->arg = arg;
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence ctx->sock = -1;
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence ctx->timeout = LWRES_DEFAULT_TIMEOUT;
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence ctx->serial = (isc_uint32_t)ctx; /* XXXMLG */
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence (void)context_connect(ctx); /* XXXMLG */
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson *contextp = ctx;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence return (LWRES_R_SUCCESS);
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson}
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafssonvoid
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafssonlwres_context_destroy(lwres_context_t **contextp)
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson{
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson lwres_context_t *ctx;
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence REQUIRE(contextp != NULL && *contextp != NULL);
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson ctx = *contextp;
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence *contextp = NULL;
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence if (ctx->sock != -1) {
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence close(ctx->sock);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence ctx->sock = -1;
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence }
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence CTXFREE(ctx, sizeof(lwres_context_t));
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence}
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrenceisc_uint32_t
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrencelwres_context_nextserial(lwres_context_t *ctx)
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence{
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence REQUIRE(ctx != NULL);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence return (ctx->serial++);
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence}
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrencevoid
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrencelwres_context_initserial(lwres_context_t *ctx, isc_uint32_t serial)
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence{
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence REQUIRE(ctx != NULL);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence ctx->serial = serial;
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence}
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrencevoid
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrencelwres_context_freemem(lwres_context_t *ctx, void *mem, size_t len)
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence{
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence REQUIRE(mem != NULL);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence REQUIRE(len != 0);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence CTXFREE(mem, len);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence}
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrencevoid *
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrencelwres_context_allocmem(lwres_context_t *ctx, size_t len)
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence{
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence REQUIRE(len != 0);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence return (CTXMALLOC(len));
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence}
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrencestatic void *
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrencelwres_malloc(void *arg, size_t len)
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence{
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence void *mem;
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence (void)arg;
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence mem = malloc(len);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence if (mem == NULL)
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence return (NULL);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence memset(mem, 0xe5, len);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence return (mem);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence}
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrencestatic void
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrencelwres_free(void *arg, void *mem, size_t len)
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence{
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence (void)arg;
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence memset(mem, 0xa9, len);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence free(mem);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence}
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencestatic int
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencecontext_connect(lwres_context_t *ctx)
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence{
fd4810861c0c0ccb9aebde94e9d289442b2630dbMark Andrews int s;
fd4810861c0c0ccb9aebde94e9d289442b2630dbMark Andrews int ret;
fd4810861c0c0ccb9aebde94e9d289442b2630dbMark Andrews struct sockaddr_in localhost;
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence memset(&localhost, 0, sizeof(localhost));
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence localhost.sin_family = AF_INET;
7ab0e69f61e61e81d489c95c7ebd981e74e7ef16Andreas Gustafsson localhost.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews localhost.sin_port = htons(LWRES_UDP_PORT);
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews if (s < 0)
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington return (LWRES_R_IOERROR);
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews ret = connect(s, (struct sockaddr *)&localhost, sizeof(localhost));
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews if (ret != 0) {
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews close(s);
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews return (LWRES_R_IOERROR);
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews }
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews ctx->sock = s;
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews return (LWRES_R_SUCCESS);
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews}
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrewsint
f6407f9a0b890bebbfd5f738d9c4aef3d3315fe9Michael Grafflwres_context_sendrecv(lwres_context_t *ctx,
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews void *sendbase, int sendlen,
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews void *recvbase, int recvlen,
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews int *recvd_len)
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews{
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews int ret;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews int ret2;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews int flags;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews struct sockaddr_in sin;
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews int fromlen;
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews fd_set readfds;
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews struct timeval timeout;
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews timeout.tv_sec = ctx->timeout;
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews timeout.tv_usec = 0;
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews ret = sendto(ctx->sock, sendbase, sendlen, 0, NULL, 0);
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews if (ret < 0)
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews return (ret);
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews if (ret != sendlen)
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews return (LWRES_R_IOERROR);
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews again:
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews flags = fcntl(ctx->sock, F_GETFL, 0);
5d83b561ad7eb84885a8ec63dee4c51b335f067aBrian Wellington flags |= O_NONBLOCK;
5d83b561ad7eb84885a8ec63dee4c51b335f067aBrian Wellington ret = fcntl(ctx->sock, F_SETFL, flags);
5d83b561ad7eb84885a8ec63dee4c51b335f067aBrian Wellington if (ret < 0)
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews return (LWRES_R_IOERROR);
613991eef6bb79b9703382aff26cddd0281da915Bob Halley
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews FD_ZERO(&readfds);
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews FD_SET(ctx->sock, &readfds);
5d83b561ad7eb84885a8ec63dee4c51b335f067aBrian Wellington ret2 = select(ctx->sock + 1, &readfds, NULL, NULL, &timeout);
5d83b561ad7eb84885a8ec63dee4c51b335f067aBrian Wellington
5d83b561ad7eb84885a8ec63dee4c51b335f067aBrian Wellington flags = fcntl(ctx->sock, F_GETFL, 0);
5d83b561ad7eb84885a8ec63dee4c51b335f067aBrian Wellington flags &= ~O_NONBLOCK;
5d83b561ad7eb84885a8ec63dee4c51b335f067aBrian Wellington ret = fcntl(ctx->sock, F_SETFL, flags);
5d83b561ad7eb84885a8ec63dee4c51b335f067aBrian Wellington if (ret < 0)
5d83b561ad7eb84885a8ec63dee4c51b335f067aBrian Wellington return (LWRES_R_IOERROR);
5d83b561ad7eb84885a8ec63dee4c51b335f067aBrian Wellington
5d83b561ad7eb84885a8ec63dee4c51b335f067aBrian Wellington /*
5d83b561ad7eb84885a8ec63dee4c51b335f067aBrian Wellington * What happened with select?
87ecd67dae468cf5c9bae213c6fa321449b2ebc2Andreas Gustafsson */
87ecd67dae468cf5c9bae213c6fa321449b2ebc2Andreas Gustafsson if (ret2 < 0)
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews return (LWRES_R_IOERROR);
87ecd67dae468cf5c9bae213c6fa321449b2ebc2Andreas Gustafsson if (ret2 == 0)
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews return (LWRES_R_TIMEOUT);
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews fromlen = sizeof(sin);
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews ret = recvfrom(ctx->sock, recvbase, recvlen, 0,
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews (struct sockaddr *)&sin, &fromlen);
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson if (ret < 0)
bcd7fdf06ca76eb2f6eb157f56b612c503e062a7Mark Andrews return (LWRES_R_IOERROR);
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews
bcd7fdf06ca76eb2f6eb157f56b612c503e062a7Mark Andrews /*
bcd7fdf06ca76eb2f6eb157f56b612c503e062a7Mark Andrews * If we got something other than what we expect, re-issue our
bcd7fdf06ca76eb2f6eb157f56b612c503e062a7Mark Andrews * recvfrom() call. This can happen if an old result comes in,
bcd7fdf06ca76eb2f6eb157f56b612c503e062a7Mark Andrews * or if someone is sending us random stuff.
bcd7fdf06ca76eb2f6eb157f56b612c503e062a7Mark Andrews */
bcd7fdf06ca76eb2f6eb157f56b612c503e062a7Mark Andrews if (sin.sin_addr.s_addr != htonl(INADDR_LOOPBACK)
bcd7fdf06ca76eb2f6eb157f56b612c503e062a7Mark Andrews || sin.sin_port != htons(LWRES_UDP_PORT))
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews goto again;
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson if (recvd_len != NULL)
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson *recvd_len = ret;
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson return (LWRES_R_SUCCESS);
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson}
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson