1
1
/*****************************************************************************
2
* $Id: m_msg.c 771 2010-03-02 23:14:07Z dun $
2
* $Id: m_msg.c 923 2011-02-25 09:47:54Z chris.m.dunlap $
3
3
*****************************************************************************
4
4
* Written by Chris Dunlap <cdunlap@llnl.gov>.
5
* Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
5
* Copyright (C) 2007-2011 Lawrence Livermore National Security, LLC.
6
6
* Copyright (C) 2002-2007 The Regents of the University of California.
9
9
* This file is part of the MUNGE Uid 'N' Gid Emporium (MUNGE).
10
* For details, see <http://home.gna.org/munge/>.
10
* For details, see <http://munge.googlecode.com/>.
12
12
* MUNGE is free software: you can redistribute it and/or modify it under
13
13
* the terms of the GNU General Public License as published by the Free
58
60
*****************************************************************************/
62
static void _get_timeval (struct timeval *tv, int msecs);
60
63
static int _msg_length (m_msg_t m, m_msg_type_t type);
61
64
static munge_err_t _msg_pack (m_msg_t m, m_msg_type_t type,
62
65
void *dst, int dstlen);
255
/* Check if the message exceeds the maximum allowed length.
257
if ((maxlen > 0) && (m->pkt_len > maxlen)) {
258
m_msg_set_err (m, EMUNGE_SOCKET,
259
strdupf ("Unable to send message: "
260
"length of %d exceeds max of %d", m->pkt_len, maxlen));
261
return (EMUNGE_BAD_LENGTH);
251
263
/* Always repack the message header.
253
265
e = _msg_pack (m, MUNGE_MSG_HDR, hdr, sizeof (hdr));
256
268
strdup ("Unable to pack message header"));
271
/* Compute iovec for response header + body.
260
iov[0].iov_base = hdr;
274
iov[0].iov_base = (void *) hdr;
261
275
nsend += iov[0].iov_len = sizeof (hdr);
262
276
iov[1].iov_base = m->pkt;
263
277
nsend += iov[1].iov_len = m->pkt_len;
265
/* An EINTR should only occur before any data is transferred.
266
* As such, it should be jiggy to restart the whole writev() if needed.
269
if ((n = writev (m->sd, iov, 2)) < 0) {
279
/* Compute maximum time to wait for transmission of message.
281
_get_timeval (&tv, MUNGE_SOCKET_TIMEOUT_MSECS);
285
if ((errno = 0, n = fd_timed_write_iov (m->sd, iov, 2, &tv, 1)) < 0) {
272
286
m_msg_set_err (m, EMUNGE_SOCKET,
273
287
strdupf ("Unable to send message: %s", strerror (errno)));
274
288
return (EMUNGE_SOCKET);
276
/* Normally, the test here for exceeding the message length would be
277
* placed before the write to prevent an error that will surely happen.
278
* But the reason it is placed here after the writev() is to allow the
279
* daemon to log the attempt to exceed the maximum message length.
280
* The daemon will abort its read after having read only the
283
if ((maxlen > 0) && (m->pkt_len > maxlen)) {
290
else if (errno == ETIMEDOUT) {
284
291
m_msg_set_err (m, EMUNGE_SOCKET,
285
strdupf ("Unable to send message: length %d exceeds max of %d",
286
m->pkt_len, maxlen));
287
return (EMUNGE_BAD_LENGTH);
292
strdup ("Unable to send message: Timed-out"));
293
return (EMUNGE_SOCKET);
295
else if (n != nsend) {
290
296
m_msg_set_err (m, EMUNGE_SOCKET,
291
297
strdupf ("Sent incomplete message: %d of %d bytes", n, nsend));
292
298
return (EMUNGE_SOCKET);
294
300
return (EMUNGE_SUCCESS);
318
326
assert (m->pkt_is_copy == 0);
319
327
assert (_msg_length (m, MUNGE_MSG_HDR) == MUNGE_MSG_HDR_SIZE);
329
/* Compute maximum time to wait for receipt of message.
331
_get_timeval (&tv, MUNGE_SOCKET_TIMEOUT_MSECS);
321
333
/* Read and validate the message header.
323
335
nrecv = sizeof (hdr);
324
if ((n = fd_read_n (m->sd, &hdr, nrecv)) < 0) {
336
if ((errno = 0, n = fd_timed_read_n (m->sd, &hdr, nrecv, &tv, 1)) < 0) {
325
337
m_msg_set_err (m, EMUNGE_SOCKET,
326
338
strdupf ("Unable to receive message header: %s",
327
339
strerror (errno)));
328
340
return (EMUNGE_SOCKET);
342
else if (errno == ETIMEDOUT) {
331
343
m_msg_set_err (m, EMUNGE_SOCKET,
332
strdup ("Received empty message header"));
344
strdup ("Unable to receive message header: Timed-out"));
333
345
return (EMUNGE_SOCKET);
335
347
else if (n != nrecv) {
353
365
else if ((maxlen > 0) && (m->pkt_len > maxlen)) {
354
366
m_msg_set_err (m, EMUNGE_SOCKET,
355
strdupf ("Received message length %d exceeding max of %d",
356
m->pkt_len, maxlen));
367
strdupf ("Unable to receive message: "
368
"length of %d exceeds max of %d", m->pkt_len, maxlen));
357
369
return (EMUNGE_BAD_LENGTH);
359
371
else if (!(m->pkt = malloc (m->pkt_len))) {
361
373
strdupf ("Unable to malloc %d bytes for message recv", n));
362
374
return (EMUNGE_NO_MEMORY);
364
else if ((n = fd_read_n (m->sd, m->pkt, m->pkt_len)) < 0) {
377
n = fd_timed_read_n (m->sd, m->pkt, m->pkt_len, &tv, 1)) < 0) {
365
378
m_msg_set_err (m, EMUNGE_SOCKET,
366
379
strdupf ("Unable to receive message body: %s", strerror (errno)));
367
380
return (EMUNGE_SOCKET);
382
else if (errno == ETIMEDOUT) {
383
m_msg_set_err (m, EMUNGE_SOCKET,
384
strdup ("Unable to receive message body: Timed-out"));
385
return (EMUNGE_SOCKET);
369
387
else if (n != m->pkt_len) {
370
388
m_msg_set_err (m, EMUNGE_SOCKET,
371
389
strdupf ("Received incomplete message body: %d of %d bytes",
421
439
* Private Functions
422
440
*****************************************************************************/
443
_get_timeval (struct timeval *tv, int msecs)
445
/* Sets [tv] to the current time adjusted forward by [msecs] milliseconds.
449
if (gettimeofday (tv, NULL) < 0) {
450
tv->tv_sec = tv->tv_usec = 0;
453
tv->tv_sec += msecs / 1000;
454
tv->tv_usec += (msecs % 1000) * 1000;
455
if (tv->tv_usec >= 1000000) {
456
tv->tv_sec += tv->tv_usec / 1000000;
457
tv->tv_usec %= 1000000;
425
465
_msg_length (m_msg_t m, m_msg_type_t type)