Annotation of embedaddon/ntp/lib/isc/unix/entropy.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2004-2007, 2009  Internet Systems Consortium, Inc. ("ISC")
        !             3:  * Copyright (C) 2000-2003  Internet Software Consortium.
        !             4:  *
        !             5:  * Permission to use, copy, modify, and/or distribute this software for any
        !             6:  * purpose with or without fee is hereby granted, provided that the above
        !             7:  * copyright notice and this permission notice appear in all copies.
        !             8:  *
        !             9:  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
        !            10:  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
        !            11:  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
        !            12:  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
        !            13:  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
        !            14:  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
        !            15:  * PERFORMANCE OF THIS SOFTWARE.
        !            16:  */
        !            17: 
        !            18: /* $Id: entropy.c,v 1.80.332.2 2009/02/16 23:47:15 tbox Exp $ */
        !            19: 
        !            20: /* \file unix/entropy.c
        !            21:  * \brief
        !            22:  * This is the system dependent part of the ISC entropy API.
        !            23:  */
        !            24: 
        !            25: #include <config.h>
        !            26: 
        !            27: #include <sys/param.h> /* Openserver 5.0.6A and FD_SETSIZE */
        !            28: #include <sys/types.h>
        !            29: #include <sys/time.h>
        !            30: #include <sys/stat.h>
        !            31: #include <sys/socket.h>
        !            32: #include <sys/un.h>
        !            33: 
        !            34: #ifdef HAVE_NANOSLEEP
        !            35: #include <time.h>
        !            36: #endif
        !            37: #include <unistd.h>
        !            38: 
        !            39: #include <isc/platform.h>
        !            40: #include <isc/strerror.h>
        !            41: 
        !            42: #ifdef ISC_PLATFORM_NEEDSYSSELECTH
        !            43: #include <sys/select.h>
        !            44: #endif
        !            45: 
        !            46: #include "errno2result.h"
        !            47: 
        !            48: /*%
        !            49:  * There is only one variable in the entropy data structures that is not
        !            50:  * system independent, but pulling the structure that uses it into this file
        !            51:  * ultimately means pulling several other independent structures here also to
        !            52:  * resolve their interdependencies.  Thus only the problem variable's type
        !            53:  * is defined here.
        !            54:  */
        !            55: #define FILESOURCE_HANDLE_TYPE int
        !            56: 
        !            57: typedef struct {
        !            58:        int     handle;
        !            59:        enum    {
        !            60:                isc_usocketsource_disconnected,
        !            61:                isc_usocketsource_connecting,
        !            62:                isc_usocketsource_connected,
        !            63:                isc_usocketsource_ndesired,
        !            64:                isc_usocketsource_wrote,
        !            65:                isc_usocketsource_reading
        !            66:        } status;
        !            67:        size_t  sz_to_recv;
        !            68: } isc_entropyusocketsource_t;
        !            69: 
        !            70: #include "../entropy.c"
        !            71: 
        !            72: static unsigned int
        !            73: get_from_filesource(isc_entropysource_t *source, isc_uint32_t desired) {
        !            74:        isc_entropy_t *ent = source->ent;
        !            75:        unsigned char buf[128];
        !            76:        int fd = source->sources.file.handle;
        !            77:        ssize_t n, ndesired;
        !            78:        unsigned int added;
        !            79: 
        !            80:        if (source->bad)
        !            81:                return (0);
        !            82: 
        !            83:        desired = desired / 8 + (((desired & 0x07) > 0) ? 1 : 0);
        !            84: 
        !            85:        added = 0;
        !            86:        while (desired > 0) {
        !            87:                ndesired = ISC_MIN(desired, sizeof(buf));
        !            88:                n = read(fd, buf, ndesired);
        !            89:                if (n < 0) {
        !            90:                        if (errno == EAGAIN || errno == EINTR)
        !            91:                                goto out;
        !            92:                        goto err;
        !            93:                }
        !            94:                if (n == 0)
        !            95:                        goto err;
        !            96: 
        !            97:                entropypool_adddata(ent, buf, n, n * 8);
        !            98:                added += n * 8;
        !            99:                desired -= n;
        !           100:        }
        !           101:        goto out;
        !           102: 
        !           103:  err:
        !           104:        (void)close(fd);
        !           105:        source->sources.file.handle = -1;
        !           106:        source->bad = ISC_TRUE;
        !           107: 
        !           108:  out:
        !           109:        return (added);
        !           110: }
        !           111: 
        !           112: static unsigned int
        !           113: get_from_usocketsource(isc_entropysource_t *source, isc_uint32_t desired) {
        !           114:        isc_entropy_t *ent = source->ent;
        !           115:        unsigned char buf[128];
        !           116:        int fd = source->sources.usocket.handle;
        !           117:        ssize_t n = 0, ndesired;
        !           118:        unsigned int added;
        !           119:        size_t sz_to_recv = source->sources.usocket.sz_to_recv;
        !           120: 
        !           121:        if (source->bad)
        !           122:                return (0);
        !           123: 
        !           124:        desired = desired / 8 + (((desired & 0x07) > 0) ? 1 : 0);
        !           125: 
        !           126:        added = 0;
        !           127:        while (desired > 0) {
        !           128:                ndesired = ISC_MIN(desired, sizeof(buf));
        !           129:  eagain_loop:
        !           130: 
        !           131:                switch ( source->sources.usocket.status ) {
        !           132:                case isc_usocketsource_ndesired:
        !           133:                        buf[0] = ndesired;
        !           134:                        if ((n = sendto(fd, buf, 1, 0, NULL, 0)) < 0) {
        !           135:                                if (errno == EWOULDBLOCK || errno == EINTR ||
        !           136:                                    errno == ECONNRESET)
        !           137:                                        goto out;
        !           138:                                goto err;
        !           139:                        }
        !           140:                        INSIST(n == 1);
        !           141:                        source->sources.usocket.status =
        !           142:                                                isc_usocketsource_wrote;
        !           143:                        goto eagain_loop;
        !           144: 
        !           145:                case isc_usocketsource_connecting:
        !           146:                case isc_usocketsource_connected:
        !           147:                        buf[0] = 1;
        !           148:                        buf[1] = ndesired;
        !           149:                        if ((n = sendto(fd, buf, 2, 0, NULL, 0)) < 0) {
        !           150:                                if (errno == EWOULDBLOCK || errno == EINTR ||
        !           151:                                    errno == ECONNRESET)
        !           152:                                        goto out;
        !           153:                                goto err;
        !           154:                        }
        !           155:                        if (n == 1) {
        !           156:                                source->sources.usocket.status =
        !           157:                                        isc_usocketsource_ndesired;
        !           158:                                goto eagain_loop;
        !           159:                        }
        !           160:                        INSIST(n == 2);
        !           161:                        source->sources.usocket.status =
        !           162:                                                isc_usocketsource_wrote;
        !           163:                        /*FALLTHROUGH*/
        !           164: 
        !           165:                case isc_usocketsource_wrote:
        !           166:                        if (recvfrom(fd, buf, 1, 0, NULL, NULL) != 1) {
        !           167:                                if (errno == EAGAIN) {
        !           168:                                        /*
        !           169:                                         * The problem of EAGAIN (try again
        !           170:                                         * later) is a major issue on HP-UX.
        !           171:                                         * Solaris actually tries the recvfrom
        !           172:                                         * call again, while HP-UX just dies.
        !           173:                                         * This code is an attempt to let the
        !           174:                                         * entropy pool fill back up (at least
        !           175:                                         * that's what I think the problem is.)
        !           176:                                         * We go to eagain_loop because if we
        !           177:                                         * just "break", then the "desired"
        !           178:                                         * amount gets borked.
        !           179:                                         */
        !           180: #ifdef HAVE_NANOSLEEP
        !           181:                                        struct timespec ts;
        !           182: 
        !           183:                                        ts.tv_sec = 0;
        !           184:                                        ts.tv_nsec = 1000000;
        !           185:                                        nanosleep(&ts, NULL);
        !           186: #else
        !           187:                                        usleep(1000);
        !           188: #endif
        !           189:                                        goto eagain_loop;
        !           190:                                }
        !           191:                                if (errno == EWOULDBLOCK || errno == EINTR)
        !           192:                                        goto out;
        !           193:                                goto err;
        !           194:                        }
        !           195:                        source->sources.usocket.status =
        !           196:                                        isc_usocketsource_reading;
        !           197:                        sz_to_recv = buf[0];
        !           198:                        source->sources.usocket.sz_to_recv = sz_to_recv;
        !           199:                        if (sz_to_recv > sizeof(buf))
        !           200:                                goto err;
        !           201:                        /*FALLTHROUGH*/
        !           202: 
        !           203:                case isc_usocketsource_reading:
        !           204:                        if (sz_to_recv != 0U) {
        !           205:                                n = recv(fd, buf, sz_to_recv, 0);
        !           206:                                if (n < 0) {
        !           207:                                        if (errno == EWOULDBLOCK ||
        !           208:                                            errno == EINTR)
        !           209:                                                goto out;
        !           210:                                        goto err;
        !           211:                                }
        !           212:                        } else
        !           213:                                n = 0;
        !           214:                        break;
        !           215: 
        !           216:                default:
        !           217:                        goto err;
        !           218:                }
        !           219: 
        !           220:                if ((size_t)n != sz_to_recv)
        !           221:                        source->sources.usocket.sz_to_recv -= n;
        !           222:                else
        !           223:                        source->sources.usocket.status =
        !           224:                                isc_usocketsource_connected;
        !           225: 
        !           226:                if (n == 0)
        !           227:                        goto out;
        !           228: 
        !           229:                entropypool_adddata(ent, buf, n, n * 8);
        !           230:                added += n * 8;
        !           231:                desired -= n;
        !           232:        }
        !           233:        goto out;
        !           234: 
        !           235:  err:
        !           236:        close(fd);
        !           237:        source->bad = ISC_TRUE;
        !           238:        source->sources.usocket.status = isc_usocketsource_disconnected;
        !           239:        source->sources.usocket.handle = -1;
        !           240: 
        !           241:  out:
        !           242:        return (added);
        !           243: }
        !           244: 
        !           245: /*
        !           246:  * Poll each source, trying to get data from it to stuff into the entropy
        !           247:  * pool.
        !           248:  */
        !           249: static void
        !           250: fillpool(isc_entropy_t *ent, unsigned int desired, isc_boolean_t blocking) {
        !           251:        unsigned int added;
        !           252:        unsigned int remaining;
        !           253:        unsigned int needed;
        !           254:        unsigned int nsource;
        !           255:        isc_entropysource_t *source;
        !           256: 
        !           257:        REQUIRE(VALID_ENTROPY(ent));
        !           258: 
        !           259:        needed = desired;
        !           260: 
        !           261:        /*
        !           262:         * This logic is a little strange, so an explanation is in order.
        !           263:         *
        !           264:         * If needed is 0, it means we are being asked to "fill to whatever
        !           265:         * we think is best."  This means that if we have at least a
        !           266:         * partially full pool (say, > 1/4th of the pool) we probably don't
        !           267:         * need to add anything.
        !           268:         *
        !           269:         * Also, we will check to see if the "pseudo" count is too high.
        !           270:         * If it is, try to mix in better data.  Too high is currently
        !           271:         * defined as 1/4th of the pool.
        !           272:         *
        !           273:         * Next, if we are asked to add a specific bit of entropy, make
        !           274:         * certain that we will do so.  Clamp how much we try to add to
        !           275:         * (DIGEST_SIZE * 8 < needed < POOLBITS - entropy).
        !           276:         *
        !           277:         * Note that if we are in a blocking mode, we will only try to
        !           278:         * get as much data as we need, not as much as we might want
        !           279:         * to build up.
        !           280:         */
        !           281:        if (needed == 0) {
        !           282:                REQUIRE(!blocking);
        !           283: 
        !           284:                if ((ent->pool.entropy >= RND_POOLBITS / 4)
        !           285:                    && (ent->pool.pseudo <= RND_POOLBITS / 4))
        !           286:                        return;
        !           287: 
        !           288:                needed = THRESHOLD_BITS * 4;
        !           289:        } else {
        !           290:                needed = ISC_MAX(needed, THRESHOLD_BITS);
        !           291:                needed = ISC_MIN(needed, RND_POOLBITS);
        !           292:        }
        !           293: 
        !           294:        /*
        !           295:         * In any case, clamp how much we need to how much we can add.
        !           296:         */
        !           297:        needed = ISC_MIN(needed, RND_POOLBITS - ent->pool.entropy);
        !           298: 
        !           299:        /*
        !           300:         * But wait!  If we're not yet initialized, we need at least
        !           301:         *      THRESHOLD_BITS
        !           302:         * of randomness.
        !           303:         */
        !           304:        if (ent->initialized < THRESHOLD_BITS)
        !           305:                needed = ISC_MAX(needed, THRESHOLD_BITS - ent->initialized);
        !           306: 
        !           307:        /*
        !           308:         * Poll each file source to see if we can read anything useful from
        !           309:         * it.  XXXMLG When where are multiple sources, we should keep a
        !           310:         * record of which one we last used so we can start from it (or the
        !           311:         * next one) to avoid letting some sources build up entropy while
        !           312:         * others are always drained.
        !           313:         */
        !           314: 
        !           315:        added = 0;
        !           316:        remaining = needed;
        !           317:        if (ent->nextsource == NULL) {
        !           318:                ent->nextsource = ISC_LIST_HEAD(ent->sources);
        !           319:                if (ent->nextsource == NULL)
        !           320:                        return;
        !           321:        }
        !           322:        source = ent->nextsource;
        !           323:  again_file:
        !           324:        for (nsource = 0; nsource < ent->nsources; nsource++) {
        !           325:                unsigned int got;
        !           326: 
        !           327:                if (remaining == 0)
        !           328:                        break;
        !           329: 
        !           330:                got = 0;
        !           331: 
        !           332:                switch ( source->type ) {
        !           333:                case ENTROPY_SOURCETYPE_FILE:
        !           334:                        got = get_from_filesource(source, remaining);
        !           335:                        break;
        !           336: 
        !           337:                case ENTROPY_SOURCETYPE_USOCKET:
        !           338:                        got = get_from_usocketsource(source, remaining);
        !           339:                        break;
        !           340:                }
        !           341: 
        !           342:                added += got;
        !           343: 
        !           344:                remaining -= ISC_MIN(remaining, got);
        !           345: 
        !           346:                source = ISC_LIST_NEXT(source, link);
        !           347:                if (source == NULL)
        !           348:                        source = ISC_LIST_HEAD(ent->sources);
        !           349:        }
        !           350:        ent->nextsource = source;
        !           351: 
        !           352:        if (blocking && remaining != 0) {
        !           353:                int fds;
        !           354: 
        !           355:                fds = wait_for_sources(ent);
        !           356:                if (fds > 0)
        !           357:                        goto again_file;
        !           358:        }
        !           359: 
        !           360:        /*
        !           361:         * Here, if there are bits remaining to be had and we can block,
        !           362:         * check to see if we have a callback source.  If so, call them.
        !           363:         */
        !           364:        source = ISC_LIST_HEAD(ent->sources);
        !           365:        while ((remaining != 0) && (source != NULL)) {
        !           366:                unsigned int got;
        !           367: 
        !           368:                got = 0;
        !           369: 
        !           370:                if (source->type == ENTROPY_SOURCETYPE_CALLBACK)
        !           371:                        got = get_from_callback(source, remaining, blocking);
        !           372: 
        !           373:                added += got;
        !           374:                remaining -= ISC_MIN(remaining, got);
        !           375: 
        !           376:                if (added >= needed)
        !           377:                        break;
        !           378: 
        !           379:                source = ISC_LIST_NEXT(source, link);
        !           380:        }
        !           381: 
        !           382:        /*
        !           383:         * Mark as initialized if we've added enough data.
        !           384:         */
        !           385:        if (ent->initialized < THRESHOLD_BITS)
        !           386:                ent->initialized += added;
        !           387: }
        !           388: 
        !           389: static int
        !           390: wait_for_sources(isc_entropy_t *ent) {
        !           391:        isc_entropysource_t *source;
        !           392:        int maxfd, fd;
        !           393:        int cc;
        !           394:        fd_set reads;
        !           395:        fd_set writes;
        !           396: 
        !           397:        maxfd = -1;
        !           398:        FD_ZERO(&reads);
        !           399:        FD_ZERO(&writes);
        !           400: 
        !           401:        source = ISC_LIST_HEAD(ent->sources);
        !           402:        while (source != NULL) {
        !           403:                if (source->type == ENTROPY_SOURCETYPE_FILE) {
        !           404:                        fd = source->sources.file.handle;
        !           405:                        if (fd >= 0) {
        !           406:                                maxfd = ISC_MAX(maxfd, fd);
        !           407:                                FD_SET(fd, &reads);
        !           408:                        }
        !           409:                }
        !           410:                if (source->type == ENTROPY_SOURCETYPE_USOCKET) {
        !           411:                        fd = source->sources.usocket.handle;
        !           412:                        if (fd >= 0) {
        !           413:                                switch (source->sources.usocket.status) {
        !           414:                                case isc_usocketsource_disconnected:
        !           415:                                        break;
        !           416:                                case isc_usocketsource_connecting:
        !           417:                                case isc_usocketsource_connected:
        !           418:                                case isc_usocketsource_ndesired:
        !           419:                                        maxfd = ISC_MAX(maxfd, fd);
        !           420:                                        FD_SET(fd, &writes);
        !           421:                                        break;
        !           422:                                case isc_usocketsource_wrote:
        !           423:                                case isc_usocketsource_reading:
        !           424:                                        maxfd = ISC_MAX(maxfd, fd);
        !           425:                                        FD_SET(fd, &reads);
        !           426:                                        break;
        !           427:                                }
        !           428:                        }
        !           429:                }
        !           430:                source = ISC_LIST_NEXT(source, link);
        !           431:        }
        !           432: 
        !           433:        if (maxfd < 0)
        !           434:                return (-1);
        !           435: 
        !           436:        cc = select(maxfd + 1, &reads, &writes, NULL, NULL);
        !           437:        if (cc < 0)
        !           438:                return (-1);
        !           439: 
        !           440:        return (cc);
        !           441: }
        !           442: 
        !           443: static void
        !           444: destroyfilesource(isc_entropyfilesource_t *source) {
        !           445:        (void)close(source->handle);
        !           446: }
        !           447: 
        !           448: static void
        !           449: destroyusocketsource(isc_entropyusocketsource_t *source) {
        !           450:        close(source->handle);
        !           451: }
        !           452: 
        !           453: /*
        !           454:  * Make a fd non-blocking
        !           455:  */
        !           456: static isc_result_t
        !           457: make_nonblock(int fd) {
        !           458:        int ret;
        !           459:        int flags;
        !           460:        char strbuf[ISC_STRERRORSIZE];
        !           461: #ifdef USE_FIONBIO_IOCTL
        !           462:        int on = 1;
        !           463: 
        !           464:        ret = ioctl(fd, FIONBIO, (char *)&on);
        !           465: #else
        !           466:        flags = fcntl(fd, F_GETFL, 0);
        !           467:        flags |= PORT_NONBLOCK;
        !           468:        ret = fcntl(fd, F_SETFL, flags);
        !           469: #endif
        !           470: 
        !           471:        if (ret == -1) {
        !           472:                isc__strerror(errno, strbuf, sizeof(strbuf));
        !           473:                UNEXPECTED_ERROR(__FILE__, __LINE__,
        !           474: #ifdef USE_FIONBIO_IOCTL
        !           475:                                 "ioctl(%d, FIONBIO, &on): %s", fd,
        !           476: #else
        !           477:                                 "fcntl(%d, F_SETFL, %d): %s", fd, flags,
        !           478: #endif
        !           479:                                 strbuf);
        !           480: 
        !           481:                return (ISC_R_UNEXPECTED);
        !           482:        }
        !           483: 
        !           484:        return (ISC_R_SUCCESS);
        !           485: }
        !           486: 
        !           487: isc_result_t
        !           488: isc_entropy_createfilesource(isc_entropy_t *ent, const char *fname) {
        !           489:        int fd;
        !           490:        struct stat _stat;
        !           491:        isc_boolean_t is_usocket = ISC_FALSE;
        !           492:        isc_boolean_t is_connected = ISC_FALSE;
        !           493:        isc_result_t ret;
        !           494:        isc_entropysource_t *source;
        !           495: 
        !           496:        REQUIRE(VALID_ENTROPY(ent));
        !           497:        REQUIRE(fname != NULL);
        !           498: 
        !           499:        LOCK(&ent->lock);
        !           500: 
        !           501:        if (stat(fname, &_stat) < 0) {
        !           502:                ret = isc__errno2result(errno);
        !           503:                goto errout;
        !           504:        }
        !           505:        /*
        !           506:         * Solaris 2.5.1 does not have support for sockets (S_IFSOCK),
        !           507:         * but it does return type S_IFIFO (the OS believes that
        !           508:         * the socket is a fifo).  This may be an issue if we tell
        !           509:         * the program to look at an actual FIFO as its source of
        !           510:         * entropy.
        !           511:         */
        !           512: #if defined(S_ISSOCK)
        !           513:        if (S_ISSOCK(_stat.st_mode))
        !           514:                is_usocket = ISC_TRUE;
        !           515: #endif
        !           516: #if defined(S_ISFIFO) && defined(sun)
        !           517:        if (S_ISFIFO(_stat.st_mode))
        !           518:                is_usocket = ISC_TRUE;
        !           519: #endif
        !           520:        if (is_usocket)
        !           521:                fd = socket(PF_UNIX, SOCK_STREAM, 0);
        !           522:        else
        !           523:                fd = open(fname, O_RDONLY | PORT_NONBLOCK, 0);
        !           524: 
        !           525:        if (fd < 0) {
        !           526:                ret = isc__errno2result(errno);
        !           527:                goto errout;
        !           528:        }
        !           529: 
        !           530:        ret = make_nonblock(fd);
        !           531:        if (ret != ISC_R_SUCCESS)
        !           532:                goto closefd;
        !           533: 
        !           534:        if (is_usocket) {
        !           535:                struct sockaddr_un sname;
        !           536: 
        !           537:                memset(&sname, 0, sizeof(sname));
        !           538:                sname.sun_family = AF_UNIX;
        !           539:                strncpy(sname.sun_path, fname, sizeof(sname.sun_path));
        !           540:                sname.sun_path[sizeof(sname.sun_path)-1] = '0';
        !           541: #ifdef ISC_PLATFORM_HAVESALEN
        !           542: #if !defined(SUN_LEN)
        !           543: #define SUN_LEN(su) \
        !           544:        (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
        !           545: #endif
        !           546:                sname.sun_len = SUN_LEN(&sname);
        !           547: #endif
        !           548: 
        !           549:                if (connect(fd, (struct sockaddr *) &sname,
        !           550:                            sizeof(struct sockaddr_un)) < 0) {
        !           551:                        if (errno != EINPROGRESS) {
        !           552:                                ret = isc__errno2result(errno);
        !           553:                                goto closefd;
        !           554:                        }
        !           555:                } else
        !           556:                        is_connected = ISC_TRUE;
        !           557:        }
        !           558: 
        !           559:        source = isc_mem_get(ent->mctx, sizeof(isc_entropysource_t));
        !           560:        if (source == NULL) {
        !           561:                ret = ISC_R_NOMEMORY;
        !           562:                goto closefd;
        !           563:        }
        !           564: 
        !           565:        /*
        !           566:         * From here down, no failures can occur.
        !           567:         */
        !           568:        source->magic = SOURCE_MAGIC;
        !           569:        source->ent = ent;
        !           570:        source->total = 0;
        !           571:        source->bad = ISC_FALSE;
        !           572:        memset(source->name, 0, sizeof(source->name));
        !           573:        ISC_LINK_INIT(source, link);
        !           574:        if (is_usocket) {
        !           575:                source->sources.usocket.handle = fd;
        !           576:                if (is_connected)
        !           577:                        source->sources.usocket.status =
        !           578:                                        isc_usocketsource_connected;
        !           579:                else
        !           580:                        source->sources.usocket.status =
        !           581:                                        isc_usocketsource_connecting;
        !           582:                source->sources.usocket.sz_to_recv = 0;
        !           583:                source->type = ENTROPY_SOURCETYPE_USOCKET;
        !           584:        } else {
        !           585:                source->sources.file.handle = fd;
        !           586:                source->type = ENTROPY_SOURCETYPE_FILE;
        !           587:        }
        !           588: 
        !           589:        /*
        !           590:         * Hook it into the entropy system.
        !           591:         */
        !           592:        ISC_LIST_APPEND(ent->sources, source, link);
        !           593:        ent->nsources++;
        !           594: 
        !           595:        UNLOCK(&ent->lock);
        !           596:        return (ISC_R_SUCCESS);
        !           597: 
        !           598:  closefd:
        !           599:        (void)close(fd);
        !           600: 
        !           601:  errout:
        !           602:        UNLOCK(&ent->lock);
        !           603: 
        !           604:        return (ret);
        !           605: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>