*** ./bind-9.2.0rc9/lib/isc/entropy.c Wed Nov 7 02:08:24 2001 --- ../bind-9.2.0rc9/lib/isc/entropy.c Fri Nov 9 22:56:10 2001 *************** *** 147,152 **** --- 147,153 ---- isc_entropysamplesource_t sample; isc_entropyfilesource_t file; isc_cbsource_t callback; + isc_entropyusocketsource_t usocket; } sources; }; *************** *** 153,158 **** --- 154,160 ---- #define ENTROPY_SOURCETYPE_SAMPLE 1 /* Type is a sample source */ #define ENTROPY_SOURCETYPE_FILE 2 /* Type is a file source */ #define ENTROPY_SOURCETYPE_CALLBACK 3 /* Type is a callback source */ + #define ENTROPY_SOURCETYPE_USOCKET 4 /* Type is a Unix socket source */ /* * The random pool "taps" *************** *** 176,182 **** --- 178,187 ---- static void destroyfilesource(isc_entropyfilesource_t *source); + static void + destroyusocketsource(isc_entropyusocketsource_t *source); + static void samplequeue_release(isc_entropy_t *ent, sample_queue_t *sq) { REQUIRE(sq->samples != NULL); *************** *** 724,729 **** --- 729,738 ---- if (! source->bad) destroyfilesource(&source->sources.file); break; + case ENTROPY_SOURCETYPE_USOCKET: + if (! source->bad) + destroyusocketsource(&source->sources.usocket); + break; case ENTROPY_SOURCETYPE_SAMPLE: samplequeue_release(ent, &source->sources.sample.samplequeue); break; *************** *** 753,758 **** --- 762,768 ---- while (source != NULL) { switch (source->type) { case ENTROPY_SOURCETYPE_FILE: + case ENTROPY_SOURCETYPE_USOCKET: break; default: return (ISC_FALSE); *************** *** 784,789 **** --- 794,800 ---- while (source != NULL) { switch(source->type) { case ENTROPY_SOURCETYPE_FILE: + case ENTROPY_SOURCETYPE_USOCKET: destroysource(&source); break; } *** ./bind-9.2.0rc9/lib/isc/unix/entropy.c Wed Nov 7 02:08:37 2001 --- ../bind-9.2.0rc9/lib/isc/unix/entropy.c Fri Nov 9 23:12:38 2001 *************** *** 25,30 **** --- 25,33 ---- #include #include + #include + #include + #include #include *************** *** 46,51 **** --- 49,66 ---- */ #define FILESOURCE_HANDLE_TYPE int + typedef struct { + int handle; + enum { + isc_usocketsource_disconnected, + isc_usocketsource_connecting, + isc_usocketsource_connected, + isc_usocketsource_wrote, + isc_usocketsource_reading + } status; + ssize_t sz_to_recv; + } isc_entropyusocketsource_t; + #include "../entropy.c" static unsigned int *************** *** 87,92 **** --- 102,179 ---- return (added); } + static unsigned int + get_from_usocketsource(isc_entropysource_t *source, isc_uint32_t desired) { + isc_entropy_t *ent = source->ent; + unsigned char buf[128]; + int fd = source->sources.usocket.handle; + ssize_t n, ndesired; + unsigned int added; + + if (source->bad) + return (0); + + desired = desired / 8 + (((desired & 0x07) > 0) ? 1 : 0); + + added = 0; + while (desired > 0) { + ndesired = ISC_MIN(desired, sizeof(buf)); + + switch ( source->sources.usocket.status ) { + + case isc_usocketsource_connecting: + case isc_usocketsource_connected: + buf[0] = 1; + buf[1] = ndesired; + if (send(fd, buf, 2, 0) < 0) { + if (errno == EWOULDBLOCK || errno == EINTR || errno == ECONNRESET) + goto out; + goto err; + } + source->sources.usocket.status = isc_usocketsource_wrote; + + + case isc_usocketsource_wrote: + if (recv(fd, buf, 1, 0) != 1) { + if (errno == EWOULDBLOCK || errno == EINTR) + goto out; + goto err; + } + source->sources.usocket.status = isc_usocketsource_reading; + source->sources.usocket.sz_to_recv = buf[0]; + + case isc_usocketsource_reading: + n = recv(fd, buf, source->sources.usocket.sz_to_recv, 0); + if (n < 0) { + if (errno == EWOULDBLOCK || errno == EINTR) + goto out; + goto err; + + } + source->sources.usocket.status = isc_usocketsource_connected; + break; + + default: + goto err; + + } + + + entropypool_adddata(ent, buf, n, n * 8); + added += n * 8; + desired -= n; + } + goto out; + + err: + close(fd); + source->bad = ISC_TRUE; + source->sources.usocket.status = isc_usocketsource_disconnected; + + out: + return (added); + } + /* * Poll each source, trying to get data from it to stuff into the entropy * pool. *************** *** 174,182 **** got = 0; ! if (source->type == ENTROPY_SOURCETYPE_FILE) ! got = get_from_filesource(source, remaining); added += got; remaining -= ISC_MIN(remaining, got); --- 261,276 ---- got = 0; ! switch ( source->type ) { ! case ENTROPY_SOURCETYPE_FILE: ! got = get_from_filesource(source, remaining); ! break; + case ENTROPY_SOURCETYPE_USOCKET: + got = get_from_usocketsource(source, remaining); + break; + } + added += got; remaining -= ISC_MIN(remaining, got); *************** *** 230,238 **** --- 324,334 ---- int maxfd, fd; int cc; fd_set reads; + fd_set writes; maxfd = -1; FD_ZERO(&reads); + FD_ZERO(&writes); source = ISC_LIST_HEAD(ent->sources); while (source != NULL) { *************** *** 243,248 **** --- 339,352 ---- FD_SET(fd, &reads); } } + if (source->type == ENTROPY_SOURCETYPE_USOCKET) { + fd = source->sources.usocket.handle; + if (fd >= 0) { + maxfd = ISC_MAX(maxfd, fd); + FD_SET(fd, &reads); + FD_SET(fd, &writes); + } + } source = ISC_LIST_NEXT(source, link); } *************** *** 249,255 **** if (maxfd < 0) return (-1); ! cc = select(maxfd + 1, &reads, NULL, NULL, NULL); if (cc < 0) return (-1); --- 353,359 ---- if (maxfd < 0) return (-1); ! cc = select(maxfd + 1, &reads, &writes, NULL, NULL); if (cc < 0) return (-1); *************** *** 261,266 **** --- 365,375 ---- close(source->handle); } + static void + destroyusocketsource(isc_entropyusocketsource_t *source) { + close(source->handle); + } + /* * Make a fd non-blocking */ *************** *** 289,294 **** --- 398,406 ---- isc_result_t isc_entropy_createfilesource(isc_entropy_t *ent, const char *fname) { int fd; + struct stat _stat; + isc_boolean_t is_usocket; + isc_boolean_t is_connected = ISC_FALSE; isc_result_t ret; isc_entropysource_t *source; *************** *** 299,313 **** source = NULL; ! fd = open(fname, O_RDONLY | O_NONBLOCK, 0); if (fd < 0) { ret = isc__errno2result(errno); goto errout; } ret = make_nonblock(fd); if (ret != ISC_R_SUCCESS) goto closefd; source = isc_mem_get(ent->mctx, sizeof(isc_entropysource_t)); if (source == NULL) { ret = ISC_R_NOMEMORY; --- 411,455 ---- source = NULL; ! if (stat(fname, &_stat) < 0) { ! ret = isc__errno2result(errno); ! goto errout; ! } ! if (_stat.st_mode & S_IFSOCK) { ! fd = socket(PF_UNIX, SOCK_STREAM, 0); ! is_usocket = ISC_TRUE; ! } ! else { ! fd = open(fname, O_RDONLY | O_NONBLOCK, 0); ! is_usocket = ISC_FALSE; ! } ! if (fd < 0) { ret = isc__errno2result(errno); goto errout; } + + ret = make_nonblock(fd); if (ret != ISC_R_SUCCESS) goto closefd; + if (is_usocket) { + struct sockaddr_un sname; + + sname.sun_family = AF_UNIX; + strcpy(sname.sun_path, fname); + + if (connect(fd, (struct sockaddr *) &sname, sizeof(struct sockaddr_un)) < 0) { + if (errno != EINPROGRESS) { + ret = isc__errno2result(errno); + goto closefd; + } + } + else + is_connected = ISC_TRUE; + } + source = isc_mem_get(ent->mctx, sizeof(isc_entropysource_t)); if (source == NULL) { ret = ISC_R_NOMEMORY; *************** *** 318,330 **** * From here down, no failures can occur. */ source->magic = SOURCE_MAGIC; - source->type = ENTROPY_SOURCETYPE_FILE; source->ent = ent; source->total = 0; source->bad = ISC_FALSE; memset(source->name, 0, sizeof(source->name)); ISC_LINK_INIT(source, link); ! source->sources.file.handle = fd; /* * Hook it into the entropy system. --- 460,482 ---- * From here down, no failures can occur. */ source->magic = SOURCE_MAGIC; source->ent = ent; source->total = 0; source->bad = ISC_FALSE; memset(source->name, 0, sizeof(source->name)); ISC_LINK_INIT(source, link); ! if (is_usocket) { ! source->sources.usocket.handle = fd; ! if (is_connected) ! source->sources.usocket.status = isc_usocketsource_connected; ! else ! source->sources.usocket.status = isc_usocketsource_connecting; ! source->type = ENTROPY_SOURCETYPE_USOCKET; ! } ! else { ! source->sources.file.handle = fd; ! source->type = ENTROPY_SOURCETYPE_FILE; ! } /* * Hook it into the entropy system. *** ./bind-9.2.0rc9/lib/isc/win32/entropy.c Wed Nov 7 02:08:47 2001 --- ../bind-9.2.0rc9/lib/isc/win32/entropy.c Fri Nov 9 23:10:53 2001 *************** *** 39,44 **** --- 39,48 ---- */ #define FILESOURCE_HANDLE_TYPE HCRYPTPROV + typedef struct { + int dummy; + } isc_entropyusocketsource_t; + #include "../entropy.c" static unsigned int *************** *** 227,232 **** --- 231,241 ---- CryptReleaseContext(source->handle, 0); } + static void + destroyusocketsource(isc_entropyusocketsource_t *source) { + return; + } + isc_result_t isc_entropy_createfilesource(isc_entropy_t *ent, const char *fname) {