From 7bee275ebe250b5e1705a997e2ee3e685d146fbd Mon Sep 17 00:00:00 2001 From: Andreas Gustafsson Date: Tue, 22 Aug 2000 16:20:21 +0000 Subject: [PATCH] added lwres_context_send(), lwres_socket_recv(), lwres_context_getsocket() to support clients doing async lookups --- lib/lwres/context.c | 114 ++++++++++++++++++++---------- lib/lwres/include/lwres/context.h | 14 +++- lib/lwres/include/lwres/result.h | 3 +- 3 files changed, 90 insertions(+), 41 deletions(-) diff --git a/lib/lwres/context.c b/lib/lwres/context.c index b680aee74c..364395a5f4 100644 --- a/lib/lwres/context.c +++ b/lib/lwres/context.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: context.c,v 1.28 2000/08/01 01:32:10 tale Exp $ */ +/* $Id: context.c,v 1.29 2000/08/22 16:20:19 gson Exp $ */ #include @@ -178,6 +178,7 @@ context_connect(lwres_context_t *ctx) { int s; int ret; struct sockaddr_in localhost; + int flags; memset(&localhost, 0, sizeof(localhost)); localhost.sin_family = AF_INET; @@ -194,54 +195,43 @@ context_connect(lwres_context_t *ctx) { return (LWRES_R_IOERROR); } + flags = fcntl(s, F_GETFL, 0); + flags |= O_NONBLOCK; + ret = fcntl(s, F_SETFL, flags); + if (ret < 0) + return (LWRES_R_IOERROR); + ctx->sock = s; return (LWRES_R_SUCCESS); } +int +lwres_context_getsocket(lwres_context_t *ctx) { + return (ctx->sock); +} + lwres_result_t -lwres_context_sendrecv(lwres_context_t *ctx, - void *sendbase, int sendlen, - void *recvbase, int recvlen, - int *recvd_len) -{ +lwres_context_send(lwres_context_t *ctx, + void *sendbase, int sendlen) { int ret; - int ret2; - struct sockaddr_in sin; - LWRES_SOCKADDR_LEN_T fromlen; - fd_set readfds; - struct timeval timeout; - - - /* - * Type of tv_sec is long, so make sure the unsigned long timeout - * does not overflow it. - */ - if (ctx->timeout <= LONG_MAX) - timeout.tv_sec = (long)ctx->timeout; - else - timeout.tv_sec = LONG_MAX; - - timeout.tv_usec = 0; - ret = sendto(ctx->sock, sendbase, sendlen, 0, NULL, 0); if (ret < 0) return (LWRES_R_IOERROR); if (ret != sendlen) return (LWRES_R_IOERROR); - again: - FD_ZERO(&readfds); - FD_SET(ctx->sock, &readfds); - ret2 = select(ctx->sock + 1, &readfds, NULL, NULL, &timeout); + return (LWRES_R_SUCCESS); +} - /* - * What happened with select? - */ - if (ret2 < 0) - return (LWRES_R_IOERROR); - if (ret2 == 0) - return (LWRES_R_TIMEOUT); +lwres_result_t +lwres_context_recv(lwres_context_t *ctx, + void *recvbase, int recvlen, + int *recvd_len) +{ + LWRES_SOCKADDR_LEN_T fromlen; + struct sockaddr_in sin; + int ret; fromlen = sizeof(sin); /* @@ -257,16 +247,62 @@ lwres_context_sendrecv(lwres_context_t *ctx, return (LWRES_R_IOERROR); /* - * If we got something other than what we expect, re-issue our - * recvfrom() call. This can happen if an old result comes in, - * or if someone is sending us random stuff. + * If we got something other than what we expect, have the caller + * wait for another packet. This can happen if an old result + * comes in, or if someone is sending us random stuff. */ if (sin.sin_addr.s_addr != htonl(INADDR_LOOPBACK) || sin.sin_port != htons(lwres_udp_port)) - goto again; + return (LWRES_R_RETRY); if (recvd_len != NULL) *recvd_len = ret; return (LWRES_R_SUCCESS); } + +lwres_result_t +lwres_context_sendrecv(lwres_context_t *ctx, + void *sendbase, int sendlen, + void *recvbase, int recvlen, + int *recvd_len) +{ + lwres_result_t result; + int ret2; + fd_set readfds; + struct timeval timeout; + + + /* + * Type of tv_sec is long, so make sure the unsigned long timeout + * does not overflow it. + */ + if (ctx->timeout <= LONG_MAX) + timeout.tv_sec = (long)ctx->timeout; + else + timeout.tv_sec = LONG_MAX; + + timeout.tv_usec = 0; + + result = lwres_context_send(ctx, sendbase, sendlen); + if (result != LWRES_R_SUCCESS) + return (result); + again: + FD_ZERO(&readfds); + FD_SET(ctx->sock, &readfds); + ret2 = select(ctx->sock + 1, &readfds, NULL, NULL, &timeout); + + /* + * What happened with select? + */ + if (ret2 < 0) + return (LWRES_R_IOERROR); + if (ret2 == 0) + return (LWRES_R_TIMEOUT); + + result = lwres_context_recv(ctx, recvbase, recvlen, recvd_len); + if (result == LWRES_R_RETRY) + goto again; + + return (result); +} diff --git a/lib/lwres/include/lwres/context.h b/lib/lwres/include/lwres/context.h index 2b14508fcc..f3c88243c8 100644 --- a/lib/lwres/include/lwres/context.h +++ b/lib/lwres/include/lwres/context.h @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: context.h,v 1.12 2000/08/10 22:44:00 gson Exp $ */ +/* $Id: context.h,v 1.13 2000/08/22 16:20:20 gson Exp $ */ #ifndef LWRES_CONTEXT_H #define LWRES_CONTEXT_H 1 @@ -109,6 +109,18 @@ lwres_context_freemem(lwres_context_t *ctx, void *mem, size_t len); void * lwres_context_allocmem(lwres_context_t *ctx, size_t len); +int +lwres_context_getsocket(lwres_context_t *ctx); + +lwres_result_t +lwres_context_send(lwres_context_t *ctx, + void *sendbase, int sendlen); + +lwres_result_t +lwres_context_recv(lwres_context_t *ctx, + void *recvbase, int recvlen, + int *recvd_len); + lwres_result_t lwres_context_sendrecv(lwres_context_t *ctx, void *sendbase, int sendlen, diff --git a/lib/lwres/include/lwres/result.h b/lib/lwres/include/lwres/result.h index 0e908394e2..f311d9d8a2 100644 --- a/lib/lwres/include/lwres/result.h +++ b/lib/lwres/include/lwres/result.h @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: result.h,v 1.10 2000/08/01 01:32:45 tale Exp $ */ +/* $Id: result.h,v 1.11 2000/08/22 16:20:21 gson Exp $ */ #ifndef LWRES_RESULT_H #define LWRES_RESULT_H 1 @@ -33,5 +33,6 @@ typedef unsigned int lwres_result_t; #define LWRES_R_UNEXPECTED 8 #define LWRES_R_TRAILINGDATA 9 #define LWRES_R_INCOMPLETE 10 +#define LWRES_R_RETRY 11 #endif /* LWRES_RESULT_H */