Author: gherzan Date: Wed Apr 21 16:16:34 2010 New Revision: 2320 Log: co: add timeout mechanism for hipl replies. Modified: trunk/community-operator/hipl.c Modified: trunk/community-operator/hipl.c ============================================================================== --- trunk/community-operator/hipl.c Wed Apr 21 12:26:42 2010 (r2319) +++ trunk/community-operator/hipl.c Wed Apr 21 16:16:34 2010 (r2320) @@ -5,6 +5,7 @@ */ #include <errno.h> +#include <poll.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> @@ -18,6 +19,7 @@ #include "hipl.h" #include "config.h" +#include "libpisa/debug.h" #include "libpisa/global.h" /* Most of the following code is a reimplementation of libinet6 functionality @@ -31,6 +33,9 @@ #define HIP_MAX_PACKET 4096 +/** Timeout (in milliseconds) for receiving a reply from HIPL */ +#define HIP_RECV_TIMEOUT 2000 + /* HIP header structure, network byte order */ struct hip_common { uint8_t payload_proto; @@ -273,9 +278,6 @@ /** * Send a HIP message to the HIP daemon and wait for an answer. * - * TODO: This function blocks indefinitely if we get no answer, implement a - * timeout mechanism, e.g. select(). - * * @param msg HIP message * @return 0 on success, -1 otherwise */ @@ -283,6 +285,7 @@ { int sock = 0, on = 1, len, result = -1; struct sockaddr_in6 addr; + struct pollfd pfd; memset(&addr, 0, sizeof(addr)); addr.sin6_family = AF_INET6; @@ -292,6 +295,9 @@ goto err; } + pfd.fd = sock; + pfd.events = POLLIN; + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) { goto err; } @@ -319,7 +325,12 @@ if (send(sock, msg, len, 0) < len) { goto err; } - /* TODO: timeout mechanism */ + + if (poll(&pfd, 1, HIP_RECV_TIMEOUT) != 1) { + PISA_DEBUG(PL_GENERIC, "Poll error/timeout waiting for HIPL reply"); + goto err; + } + if (recv(sock, msg, HIP_MAX_PACKET, 0) < 0) { goto err; }