EDG_WLPR_PROXY_NOT_REGISTERED,
EDG_WLPR_PROXY_EXPIRED,
EDG_WLPR_ERROR_VOMS,
+ EDG_WLPR_ERROR_TIMEOUT,
+ EDG_WLPR_ERROR_ERRNO,
} edg_wlpr_ErrorCode;
/**
-module.version = 1.0.12
+module.version = 1.0.13
module.age = 1
decode_response(const char *msg, const size_t msg_len, edg_wlpr_Response *response);
static int
-do_connect(char *socket_name, int *sock);
+do_connect(char *socket_name, struct timeval *timeout, int *sock);
static int
-send_request(int sock, edg_wlpr_Request *request, edg_wlpr_Response *response);
-
+send_request(int sock, struct timeval *timeout, edg_wlpr_Request *request, edg_wlpr_Response *response);
static int
encode_request(edg_wlpr_Request *request, char **msg)
}
static int
-do_connect(char *socket_name, int *sock)
+do_connect(char *socket_name, struct timeval *timeout, int *sock)
{
struct sockaddr_un my_addr;
int s;
int ret;
+ struct timeval before,after,to;
+ int sock_err;
+ socklen_t err_len;
assert(sock != NULL);
memset(&my_addr, 0, sizeof(my_addr));
return errno;
}
+ if (timeout) {
+ int flags = fcntl(s, F_GETFL, 0);
+ if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0)
+ return errno;
+ }
+
my_addr.sun_family = AF_UNIX;
strncpy(my_addr.sun_path, socket_name, sizeof(my_addr.sun_path));
ret = connect(s, (struct sockaddr *) &my_addr, sizeof(my_addr));
if (ret == -1) {
- close(s);
- return errno;
+ if (errno == EINPROGRESS) {
+ fd_set fds;
+
+ FD_ZERO(&fds);
+ FD_SET(s, &fds);
+ memcpy(&to, timeout, sizeof(to));
+ gettimeofday(&before,NULL);
+ switch (select(s+1, NULL, &fds, NULL, &to)) {
+ case -1: close(s);
+ return errno;
+ case 0: close(s);
+ return EDG_WLPR_ERROR_TIMEOUT;
+ }
+ gettimeofday(&after,NULL);
+ if (edg_wlpr_DecrementTimeout(timeout, before, after)) {
+ close (s);
+ return EDG_WLPR_ERROR_TIMEOUT;
+ }
+
+ err_len = sizeof sock_err;
+ if (getsockopt(s,SOL_SOCKET,SO_ERROR,&sock_err,&err_len)) {
+ close(s);
+ return errno;
+ }
+ if (sock_err) {
+ close(s);
+ errno = sock_err;
+ return errno;
+ }
+ } else {
+ close(s);
+ return errno;
+ }
}
*sock = s;
}
static int
-send_request(int sock, edg_wlpr_Request *request, edg_wlpr_Response *response)
+send_request(int sock, struct timeval *timeout, edg_wlpr_Request *request, edg_wlpr_Response *response)
{
int ret;
char *buf = NULL;
if (ret)
return ret;
- ret = edg_wlpr_Write(sock, buf, strlen(buf) + 1);
+ ret = edg_wlpr_Write(sock, timeout, buf, strlen(buf) + 1);
free(buf);
if (ret)
return ret;
- ret = edg_wlpr_Read(sock, &buf, &buf_len);
+ ret = edg_wlpr_Read(sock, timeout, &buf, &buf_len);
if (ret)
return ret;
char sockname[1024];
int ret;
int sock;
+ struct timeval timeout;
+ const char *s = NULL;
+ double d;
+
+ s = getenv("GLITE_PR_TIMEOUT");
+ d = s ? atof(s) : GLITE_PR_TIMEOUT_DEFAULT;
+ timeout.tv_sec = (long) d;
+ timeout.tv_usec = (long) ((d-timeout.tv_sec) * 1e6);
snprintf(sockname, sizeof(sockname), "%s%d",
DGPR_REG_SOCKET_NAME_ROOT, getuid());
- ret = do_connect(sockname, &sock);
+ ret = do_connect(sockname, &timeout, &sock);
if (ret)
return ret;
- ret = send_request(sock, request, response);
+ ret = send_request(sock, &timeout, request, response);
close(sock);
return ret;
"Proxy not registered",
"Proxy expired",
"VOMS error",
+ "Operation timed out",
+ "System error"
};
const char *
#ident "$Header$"
/* nread() and nwrite() never return partial data */
-static size_t
-nread(int sock, char *buf, size_t buf_len)
+static int
+nread(int sock, struct timeval *to, char *buf, size_t buf_len, size_t *read_len)
{
size_t count;
size_t remain = buf_len;
char *cbuf = buf;
+ fd_set fds;
+ struct timeval timeout,before,after;
+ int ret;
+
+ if (to) {
+ memcpy(&timeout,to,sizeof(timeout));
+ gettimeofday(&before,NULL);
+ }
while (remain > 0) {
+ FD_ZERO(&fds);
+ FD_SET(sock,&fds);
+ switch (select(sock+1, &fds, NULL, NULL, to ? &timeout : NULL)) {
+ case 0:
+ ret = EDG_WLPR_ERROR_TIMEOUT;
+ goto end;
+ case -1:
+ ret = EDG_WLPR_ERROR_ERRNO;
+ goto end;
+ }
+
count = read(sock, cbuf, remain);
if (count < 0) {
if (errno == EINTR)
continue;
- else
- return count;
+ else {
+ ret = EDG_WLPR_ERROR_ERRNO;
+ goto end;
+ }
} else
if (count == 0) {
- return count;
+ *read_len = 0;
+ return 0;
}
cbuf += count;
remain -= count;
}
- return buf_len;
+ *read_len = buf_len;
+ ret = 0;
+
+end:
+ if (to) {
+ gettimeofday(&after,NULL);
+ edg_wlpr_DecrementTimeout(to, before, after);
+ if (to->tv_sec < 0) {
+ to->tv_sec = 0;
+ to->tv_usec = 0;
+ }
+ }
+
+ return ret;
}
static size_t
-nwrite(int sock, const char *buf, size_t buf_len)
+nwrite(int sock, struct timeval *to, const char *buf, size_t buf_len)
{
const char *cbuf = buf;
size_t count;
size_t remain = buf_len;
+ fd_set fds;
+ struct timeval timeout,before,after;
+ int ret;
+
+ if (to) {
+ memcpy(&timeout,to,sizeof(timeout));
+ gettimeofday(&before,NULL);
+ }
while (remain > 0) {
+ FD_ZERO(&fds);
+ FD_SET(sock,&fds);
+ switch (select(sock+1, NULL, &fds, NULL, to ? &timeout : NULL)) {
+ case 0: ret = EDG_WLPR_ERROR_TIMEOUT;
+ goto end;
+ case -1: ret = EDG_WLPR_ERROR_ERRNO;
+ goto end;
+ }
+
count = write(sock, cbuf, remain);
if (count < 0) {
if (errno == EINTR)
continue;
- else
- return count;
+ else {
+ ret = EDG_WLPR_ERROR_ERRNO;
+ goto end;
+ }
}
cbuf += count;
remain -= count;
}
- return buf_len;
+ ret = buf_len;
+
+end:
+ if (to) {
+ gettimeofday(&after,NULL);
+ edg_wlpr_DecrementTimeout(to, before, after);
+ if (to->tv_sec < 0) {
+ to->tv_sec = 0;
+ to->tv_usec = 0;
+ }
+ }
+
+ return ret;
}
int
-edg_wlpr_Read(int sock, char **buf, size_t *buf_len)
+edg_wlpr_Read(int sock, struct timeval *timeout, char **buf, size_t *buf_len)
{
int ret;
unsigned char length[4];
+ size_t len;
- ret = nread(sock, length, 4);
- if (ret == -1) {
+ ret = nread(sock, timeout, length, 4, &len);
+ if (ret) {
*buf_len = 0;
- return errno;
+ return ret;
}
- if (ret < 4) {
+ if (len != 4) {
*buf_len = 0;
return EDG_WLPR_ERROR_UNEXPECTED_EOF; /* XXX vraci i kdyz peer spadne a zavre trubku */
}
if (*buf == NULL)
return ENOMEM;
- ret = nread(sock, *buf, *buf_len);
- if (ret != *buf_len) {
+ ret = nread(sock, timeout, *buf, *buf_len, &len);
+ if (ret)
+ return ret;
+
+ if (len != *buf_len) {
free(*buf);
*buf_len = 0;
- return errno;
+ return EDG_WLPR_ERROR_UNEXPECTED_EOF; /* XXX */
}
return 0;
}
int
-edg_wlpr_Write(int sock, char *buf, size_t buf_len)
+edg_wlpr_Write(int sock, struct timeval *timeout, char *buf, size_t buf_len)
{
unsigned char length[4];
length[2] = (buf_len >> 8) & 0xFF;
length[3] = (buf_len >> 0) & 0xFF;
- if (nwrite(sock, length, 4) != 4 ||
- nwrite(sock, buf, buf_len) != buf_len)
+ if (nwrite(sock, timeout, length, 4) != 4 ||
+ nwrite(sock, timeout, buf, buf_len) != buf_len)
return errno;
return 0;
*num = atol(str); /* XXX */
return 0;
}
+
+int
+edg_wlpr_DecrementTimeout(struct timeval *timeout, struct timeval before, struct timeval after)
+{
+ (*timeout).tv_sec = (*timeout).tv_sec - (after.tv_sec - before.tv_sec);
+ (*timeout).tv_usec = (*timeout).tv_usec - (after.tv_usec - before.tv_usec);
+ while ( (*timeout).tv_usec < 0) {
+ (*timeout).tv_sec--;
+ (*timeout).tv_usec += 1000000;
+ }
+
+ if ( ((*timeout).tv_sec < 0) || (((*timeout).tv_sec == 0) && ((*timeout).tv_usec == 0)) ) return(1);
+ else return(0);
+}
ret = 0;
end:
+ if (proxy)
+ globus_gsi_cred_handle_destroy(proxy);
if (result)
ret = EDG_WLPR_ERROR_GENERIC;
#define DGPR_RETRIEVE_DEFAULT_HOURS 10
+#define GLITE_PR_TIMEOUT_DEFAULT 120
+
typedef struct {
char *version;
edg_wlpr_Command command;
char *value, const char *separator);
int
-edg_wlpr_Read(int sock, char **buf, size_t *buf_len);
+edg_wlpr_Read(int sock, struct timeval *timeout, char **buf, size_t *buf_len);
int
-edg_wlpr_Write(int sock, char *buf, size_t buf_len);
+edg_wlpr_Write(int sock, struct timeval *timeout, char *buf, size_t buf_len);
void
edg_wlpr_CleanRequest(edg_wlpr_Request *request);
int
edg_wlpr_RequestSend(edg_wlpr_Request *request, edg_wlpr_Response *response);
+int
+edg_wlpr_DecrementTimeout(struct timeval *timeout, struct timeval before, struct timeval after);
+
#endif /* RENEWAL_LOCL_H */
char *vomsconf = NULL;
static volatile int die = 0, child_died = 0;
+double default_timeout = 0;
static struct option opts[] = {
{ "help", no_argument, NULL, 'h' },
edg_wlpr_Response response;
edg_wlpr_Request request;
command_table *command;
+ struct timeval timeout;
memset(&request, 0, sizeof(request));
memset(&response, 0, sizeof(response));
- ret = edg_wlpr_Read(sock, &buf, &buf_len);
+ timeout.tv_sec = (long) default_timeout;
+ timeout.tv_usec = (long) ((default_timeout - timeout.tv_sec) * 1e6);
+
+ ret = edg_wlpr_Read(sock, &timeout, &buf, &buf_len);
if (ret) {
edg_wlpr_Log(LOG_ERR, "Error reading from client: %s",
edg_wlpr_GetErrorString(ret));
if (ret)
goto end;
- ret = edg_wlpr_Write(sock, buf, strlen(buf) + 1);
+ ret = edg_wlpr_Write(sock, &timeout, buf, strlen(buf) + 1);
free(buf);
if (ret) {
edg_wlpr_Log(LOG_ERR, "Error sending response to client: %s",
int newsock;
struct sockaddr_un client_addr;
int client_addr_len = sizeof(client_addr);
-#if 0
- next_renewal = LONG_MAX;
- size_of_proxies = PROXIES_ALLOC_SIZE;
- proxies = malloc((size_of_proxies) * sizeof(struct guarded_proxy *));
- if (proxies == NULL) {
- return ENOMEM;
- }
- proxies[0] = NULL;
-#endif
+ int flags;
while (!die) {
}
edg_wlpr_Log(LOG_DEBUG, "Got connection");
+ flags = fcntl(newsock, F_GETFL, 0);
+ if (fcntl(newsock, F_SETFL, flags | O_NONBLOCK) < 0) {
+ edg_wlpr_Log(LOG_ERR, "Can't set O_NONBLOCK mode (%s), closing.\n",
+ strerror(errno));
+ close(newsock);
+ continue;
+ }
+
proto(newsock);
edg_wlpr_Log(LOG_DEBUG, "Connection closed");
return errno;
}
- ret = listen(s, 5); /* XXX enough ? */
+ ret = listen(s, 50);
if (ret == -1) {
edg_wlpr_Log(LOG_ERR, "listen(): %s", strerror(errno));
close(s);
int ret;
pid_t pid;
struct sigaction sa;
+ const char *s = NULL;
progname = strrchr(argv[0],'/');
if (progname) progname++;
if (cadir)
setenv("X509_CERT_DIR", cadir, 1);
+ s = getenv("GLITE_PR_TIMEOUT");
+ default_timeout = s ? atof(s) : GLITE_PR_TIMEOUT_DEFAULT;
+
memset(&sa,0,sizeof(sa));
sa.sa_handler = catchsig;
sigaction(SIGINT,&sa,NULL);