~ubuntu-branches/ubuntu/vivid/munge/vivid

« back to all changes in this revision

Viewing changes to src/libcommon/m_msg.c

  • Committer: Bazaar Package Importer
  • Author(s): Gennaro Oliva
  • Date: 2011-02-28 20:41:12 UTC
  • mfrom: (6.1.6 sid)
  • Revision ID: james.westby@ubuntu.com-20110228204112-2lc8ss9geeusv5uo
Tags: 0.5.10-1
* New upstream release 
* Updated copyright, homepage, watch thanks to Chris Dunlap
* Standards version upgraded to 3.9.1.0 (no changes) 
* Switch to dpkg-source 3.0 (quilt) format
* Added explicit dependency by the same version of libmunge for munge

Show diffs side-by-side

added added

removed removed

Lines of Context:
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.
7
7
 *  UCRL-CODE-155910.
8
8
 *
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/>.
11
11
 *
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
39
39
#include <munge.h>
40
40
#include <stdlib.h>
41
41
#include <string.h>
 
42
#include <sys/time.h>                   /* gettimeofday */
42
43
#include <sys/uio.h>
43
44
#include <unistd.h>
44
45
#include "fd.h"
45
46
#include "m_msg.h"
 
47
#include "munge_defs.h"
46
48
#include "str.h"
47
49
 
48
50
 
57
59
 *  Prototypes
58
60
 *****************************************************************************/
59
61
 
 
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);
198
201
 *    and an error returned.
199
202
 *  Returns a standard munge error code.
200
203
 */
201
 
    munge_err_t   e;
202
 
    int           n, nsend;
203
 
    uint8_t       hdr [MUNGE_MSG_HDR_SIZE];
204
 
    struct iovec  iov [2];
 
204
    munge_err_t     e;
 
205
    int             n, nsend;
 
206
    uint8_t         hdr [MUNGE_MSG_HDR_SIZE];
 
207
    struct iovec    iov [2];
 
208
    struct timeval  tv;
205
209
 
206
210
    assert (m != NULL);
207
211
    assert (m->sd >= 0);
248
252
            return (e);
249
253
        }
250
254
    }
 
255
    /*  Check if the message exceeds the maximum allowed length.
 
256
     */
 
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);
 
262
    }
251
263
    /*  Always repack the message header.
252
264
     */
253
265
    e = _msg_pack (m, MUNGE_MSG_HDR, hdr, sizeof (hdr));
256
268
            strdup ("Unable to pack message header"));
257
269
        return (e);
258
270
    }
 
271
    /*  Compute iovec for response header + body.
 
272
     */
259
273
    nsend = 0;
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;
264
278
 
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.
267
 
     */
268
 
again:
269
 
    if ((n = writev (m->sd, iov, 2)) < 0) {
270
 
        if (errno == EINTR)
271
 
            goto again;
 
279
    /*  Compute maximum time to wait for transmission of message.
 
280
     */
 
281
    _get_timeval (&tv, MUNGE_SOCKET_TIMEOUT_MSECS);
 
282
 
 
283
    /*  Send the message.
 
284
     */
 
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);
275
289
    }
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
281
 
     *    m_msg_head struct.
282
 
     */
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);
288
294
    }
289
 
    if (n != nsend) {
 
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);
293
299
    }
294
300
    return (EMUNGE_SUCCESS);
 
301
 
295
302
}
296
303
 
297
304
 
307
314
 *    and an error returned.
308
315
 *  Returns a standard munge error code.
309
316
 */
310
 
    int      n, nrecv;
311
 
    uint8_t  hdr [MUNGE_MSG_HDR_SIZE];
 
317
    int             n, nrecv;
 
318
    uint8_t         hdr [MUNGE_MSG_HDR_SIZE];
 
319
    struct timeval  tv;
312
320
 
313
321
    assert (m != NULL);
314
322
    assert (m->sd >= 0);
318
326
    assert (m->pkt_is_copy == 0);
319
327
    assert (_msg_length (m, MUNGE_MSG_HDR) == MUNGE_MSG_HDR_SIZE);
320
328
 
 
329
    /*  Compute maximum time to wait for receipt of message.
 
330
     */
 
331
    _get_timeval (&tv, MUNGE_SOCKET_TIMEOUT_MSECS);
 
332
 
321
333
    /*  Read and validate the message header.
322
334
     */
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);
329
341
    }
330
 
    else if (n == 0) {
 
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);
334
346
    }
335
347
    else if (n != nrecv) {
352
364
    }
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);
358
370
    }
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);
363
375
    }
364
 
    else if ((n = fd_read_n (m->sd, m->pkt, m->pkt_len)) < 0) {
 
376
    else if ((errno = 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);
368
381
    }
 
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);
 
386
    }
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
 *****************************************************************************/
423
441
 
 
442
static void
 
443
_get_timeval (struct timeval *tv, int msecs)
 
444
{
 
445
/*  Sets [tv] to the current time adjusted forward by [msecs] milliseconds.
 
446
 */
 
447
    assert (tv != NULL);
 
448
 
 
449
    if (gettimeofday (tv, NULL) < 0) {
 
450
        tv->tv_sec = tv->tv_usec = 0;
 
451
    }
 
452
    if (msecs > 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;
 
458
        }
 
459
    }
 
460
    return;
 
461
}
 
462
 
 
463
 
424
464
static int
425
465
_msg_length (m_msg_t m, m_msg_type_t type)
426
466
{