//.........这里部分代码省略.........
/*
* In any case, clamp how much we need to how much we can add.
*/
needed = ISC_MIN (needed, RND_POOLBITS - ent->pool.entropy);
/*
* But wait! If we're not yet initialized, we need at least
* THRESHOLD_BITS
* of randomness.
*/
if (ent->initialized < THRESHOLD_BITS)
needed = ISC_MAX (needed, THRESHOLD_BITS - ent->initialized);
/*
* Poll each file source to see if we can read anything useful from
* it. XXXMLG When where are multiple sources, we should keep a
* record of which one we last used so we can start from it (or the
* next one) to avoid letting some sources build up entropy while
* others are always drained.
*/
added = 0;
remaining = needed;
if (ent->nextsource == NULL)
{
ent->nextsource = ISC_LIST_HEAD (ent->sources);
if (ent->nextsource == NULL)
return;
}
source = ent->nextsource;
again_file:
for (nsource = 0; nsource < ent->nsources; nsource++)
{
unsigned int got;
if (remaining == 0)
break;
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);
source = ISC_LIST_NEXT (source, link);
if (source == NULL)
source = ISC_LIST_HEAD (ent->sources);
}
ent->nextsource = source;
if (blocking && remaining != 0)
{
int fds;
fds = wait_for_sources (ent);
if (fds > 0)
goto again_file;
}
/*
* Here, if there are bits remaining to be had and we can block,
* check to see if we have a callback source. If so, call them.
*/
source = ISC_LIST_HEAD (ent->sources);
while ((remaining != 0) && (source != NULL))
{
unsigned int got;
got = 0;
if (source->type == ENTROPY_SOURCETYPE_CALLBACK)
got = get_from_callback (source, remaining, blocking);
added += got;
remaining -= ISC_MIN (remaining, got);
if (added >= needed)
break;
source = ISC_LIST_NEXT (source, link);
}
/*
* Mark as initialized if we've added enough data.
*/
if (ent->initialized < THRESHOLD_BITS)
ent->initialized += added;
}
isc_result_t
dns_diff_print(dns_diff_t *diff, FILE *file) {
isc_result_t result;
dns_difftuple_t *t;
char *mem = NULL;
unsigned int size = 2048;
const char *op = NULL;
REQUIRE(DNS_DIFF_VALID(diff));
mem = isc_mem_get(diff->mctx, size);
if (mem == NULL)
return (ISC_R_NOMEMORY);
for (t = ISC_LIST_HEAD(diff->tuples); t != NULL;
t = ISC_LIST_NEXT(t, link))
{
isc_buffer_t buf;
isc_region_t r;
dns_rdatalist_t rdl;
dns_rdataset_t rds;
dns_rdata_t rd = DNS_RDATA_INIT;
result = diff_tuple_tordataset(t, &rd, &rdl, &rds);
if (result != ISC_R_SUCCESS) {
UNEXPECTED_ERROR(__FILE__, __LINE__,
"diff_tuple_tordataset failed: %s",
dns_result_totext(result));
result = ISC_R_UNEXPECTED;
goto cleanup;
}
again:
isc_buffer_init(&buf, mem, size);
result = dns_rdataset_totext(&rds, &t->name,
ISC_FALSE, ISC_FALSE, &buf);
if (result == ISC_R_NOSPACE) {
isc_mem_put(diff->mctx, mem, size);
size += 1024;
mem = isc_mem_get(diff->mctx, size);
if (mem == NULL) {
result = ISC_R_NOMEMORY;
goto cleanup;
}
goto again;
}
if (result != ISC_R_SUCCESS)
goto cleanup;
/*
* Get rid of final newline.
*/
INSIST(buf.used >= 1 &&
((char *) buf.base)[buf.used-1] == '\n');
buf.used--;
isc_buffer_usedregion(&buf, &r);
switch (t->op) {
case DNS_DIFFOP_EXISTS: op = "exists"; break;
case DNS_DIFFOP_ADD: op = "add"; break;
case DNS_DIFFOP_DEL: op = "del"; break;
case DNS_DIFFOP_ADDRESIGN: op = "add re-sign"; break;
case DNS_DIFFOP_DELRESIGN: op = "del re-sign"; break;
}
if (file != NULL)
fprintf(file, "%s %.*s\n", op, (int) r.length,
(char *) r.base);
else
isc_log_write(DIFF_COMMON_LOGARGS, ISC_LOG_DEBUG(7),
"%s %.*s", op, (int) r.length,
(char *) r.base);
}
result = ISC_R_SUCCESS;
cleanup:
if (mem != NULL)
isc_mem_put(diff->mctx, mem, size);
return (result);
}
开发者ID:ElRevo,项目名称:xia-core,代码行数:79,代码来源:diff.c
示例5: isc__app_ctxrun
ISC_APPFUNC_SCOPE isc_result_t
isc__app_ctxrun(isc_appctx_t *ctx0) {
isc__appctx_t *ctx = (isc__appctx_t *)ctx0;
int result;
isc_event_t *event, *next_event;
isc_task_t *task;
sigset_t sset;
char strbuf[ISC_STRERRORSIZE];
#ifdef HAVE_SIGWAIT
int sig;
#endif
REQUIRE(VALID_APPCTX(ctx));
#ifdef HAVE_LINUXTHREADS
REQUIRE(main_thread == pthread_self());
#endif
LOCK(&ctx->lock);
if (!ctx->running) {
ctx->running = ISC_TRUE;
/*
* Post any on-run events (in FIFO order).
*/
for (event = ISC_LIST_HEAD(ctx->on_run);
event != NULL;
event = next_event) {
next_event = ISC_LIST_NEXT(event, ev_link);
ISC_LIST_UNLINK(ctx->on_run, event, ev_link);
task = event->ev_sender;
event->ev_sender = NULL;
isc_task_sendanddetach(&task, &event);
}
}
UNLOCK(&ctx->lock);
#ifndef HAVE_SIGWAIT
/*
* Catch SIGHUP.
*
* We do this here to ensure that the signal handler is installed
* (i.e. that it wasn't a "one-shot" handler).
*/
if (ctx == &isc_g_appctx) {
result = handle_signal(SIGHUP, reload_action);
if (result != ISC_R_SUCCESS)
return (ISC_R_SUCCESS);
}
#endif
/*
* When we are using multiple contexts, we don't rely on signals.
*/
if (ctx == &isc_g_appctx) {
/*
* There is no danger if isc_app_shutdown() is called before we wait
* for signals. Signals are blocked, so any such signal will simply
* be made pending and we will get it when we call sigwait().
*/
while (!ctx->want_shutdown) {
#ifdef HAVE_SIGWAIT
/*
* Wait for SIGHUP, SIGINT, or SIGTERM.
*/
if (sigemptyset(&sset) != 0 ||
sigaddset(&sset, SIGHUP) != 0 ||
sigaddset(&sset, SIGINT) != 0 ||
sigaddset(&sset, SIGTERM) != 0) {
isc__strerror(errno, strbuf, sizeof(strbuf));
UNEXPECTED_ERROR(__FILE__, __LINE__,
"isc_app_run() sigsetops: %s", strbuf);
return (ISC_R_UNEXPECTED);
}
#ifndef HAVE_UNIXWARE_SIGWAIT
result = sigwait(&sset, &sig);
if (result == 0) {
if (sig == SIGINT || sig == SIGTERM)
ctx->want_shutdown = ISC_TRUE;
else if (sig == SIGHUP)
ctx->want_reload = ISC_TRUE;
}
#else /* Using UnixWare sigwait semantics. */
sig = sigwait(&sset);
if (sig >= 0) {
if (sig == SIGINT || sig == SIGTERM)
ctx->want_shutdown = ISC_TRUE;
else if (sig == SIGHUP)
ctx->want_reload = ISC_TRUE;
}
#endif /* HAVE_UNIXWARE_SIGWAIT */
#else /* Don't have sigwait(). */
//.........这里部分代码省略.........
static isc_result_t
diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver,
isc_boolean_t warn)
{
dns_difftuple_t *t;
dns_dbnode_t *node = NULL;
isc_result_t result;
char namebuf[DNS_NAME_FORMATSIZE];
char typebuf[DNS_RDATATYPE_FORMATSIZE];
char classbuf[DNS_RDATACLASS_FORMATSIZE];
REQUIRE(DNS_DIFF_VALID(diff));
REQUIRE(DNS_DB_VALID(db));
t = ISC_LIST_HEAD(diff->tuples);
while (t != NULL) {
dns_name_t *name;
INSIST(node == NULL);
name = &t->name;
/*
* Find the node.
* We create the node if it does not exist.
* This will cause an empty node to be created if the diff
* contains a deletion of an RR at a nonexistent name,
* but such diffs should never be created in the first
* place.
*/
while (t != NULL && dns_name_equal(&t->name, name)) {
dns_rdatatype_t type, covers;
dns_diffop_t op;
dns_rdatalist_t rdl;
dns_rdataset_t rds;
dns_rdataset_t ardataset;
dns_rdataset_t *modified = NULL;
op = t->op;
type = t->rdata.type;
covers = rdata_covers(&t->rdata);
/*
* Collect a contiguous set of updates with
* the same operation (add/delete) and RR type
* into a single rdatalist so that the
* database rrset merging/subtraction code
* can work more efficiently than if each
* RR were merged into / subtracted from
* the database separately.
*
* This is done by linking rdata structures from the
* diff into "rdatalist". This uses the rdata link
* field, not the diff link field, so the structure
* of the diff itself is not affected.
*/
rdl.type = type;
rdl.covers = covers;
rdl.rdclass = t->rdata.rdclass;
rdl.ttl = t->ttl;
ISC_LIST_INIT(rdl.rdata);
ISC_LINK_INIT(&rdl, link);
node = NULL;
if (type != dns_rdatatype_nsec3 &&
covers != dns_rdatatype_nsec3)
CHECK(dns_db_findnode(db, name, ISC_TRUE,
&node));
else
CHECK(dns_db_findnsec3node(db, name, ISC_TRUE,
&node));
while (t != NULL &&
dns_name_equal(&t->name, name) &&
t->op == op &&
t->rdata.type == type &&
rdata_covers(&t->rdata) == covers)
{
dns_name_format(name, namebuf, sizeof(namebuf));
dns_rdatatype_format(t->rdata.type, typebuf,
sizeof(typebuf));
dns_rdataclass_format(t->rdata.rdclass,
classbuf,
sizeof(classbuf));
if (t->ttl != rdl.ttl && warn)
isc_log_write(DIFF_COMMON_LOGARGS,
ISC_LOG_WARNING,
"'%s/%s/%s': TTL differs in "
"rdataset, adjusting "
"%lu -> %lu",
namebuf, typebuf, classbuf,
(unsigned long) t->ttl,
(unsigned long) rdl.ttl);
ISC_LIST_APPEND(rdl.rdata, &t->rdata, link);
t = ISC_LIST_NEXT(t, link);
}
/*
* Convert the rdatalist into a rdataset.
*/
//.........这里部分代码省略.........
开发者ID:ElRevo,项目名称:xia-core,代码行数:101,代码来源:diff.c
示例8: resolve_ns
static void
resolve_ns(isc_task_t *task, isc_event_t *event) {
struct probe_trans *trans = event->ev_arg;
dns_clientresevent_t *rev = (dns_clientresevent_t *)event;
dns_name_t *name;
dns_rdataset_t *rdataset;
isc_result_t result = ISC_R_SUCCESS;
dns_rdata_t rdata = DNS_RDATA_INIT;
struct probe_ns *pns;
REQUIRE(task == probe_task);
REQUIRE(trans->inuse == ISC_TRUE);
INSIST(outstanding_probes > 0);
for (name = ISC_LIST_HEAD(rev->answerlist); name != NULL;
name = ISC_LIST_NEXT(name, link)) {
for (rdataset = ISC_LIST_HEAD(name->list);
rdataset != NULL;
rdataset = ISC_LIST_NEXT(rdataset, link)) {
(void)print_rdataset(rdataset, name);
if (rdataset->type != dns_rdatatype_ns)
continue;
for (result = dns_rdataset_first(rdataset);
result == ISC_R_SUCCESS;
result = dns_rdataset_next(rdataset)) {
dns_rdata_ns_t ns;
dns_rdataset_current(rdataset, &rdata);
/*
* Extract the name from the NS record.
*/
result = dns_rdata_tostruct(&rdata, &ns, NULL);
if (result != ISC_R_SUCCESS)
continue;
pns = isc_mem_get(mctx, sizeof(*pns));
if (pns == NULL) {
fprintf(stderr,
"resolve_ns: mem_get failed");
result = ISC_R_NOMEMORY;
POST(result);
/*
* XXX: should we continue with the
* available servers anyway?
*/
goto cleanup;
}
dns_fixedname_init(&pns->fixedname);
pns->name =
dns_fixedname_name(&pns->fixedname);
ISC_LINK_INIT(pns, link);
ISC_LIST_APPEND(trans->nslist, pns, link);
ISC_LIST_INIT(pns->servers);
dns_name_copy(&ns.name, pns->name, NULL);
dns_rdata_reset(&rdata);
dns_rdata_freestruct(&ns);
}
}
}
cleanup:
dns_client_freeresanswer(client, &rev->answerlist);
dns_client_destroyrestrans(&trans->resid);
isc_event_free(&event);
if (!ISC_LIST_EMPTY(trans->nslist)) {
/* Go get addresses of NSes */
trans->current_ns = ISC_LIST_HEAD(trans->nslist);
result = fetch_nsaddress(trans);
} else
result = ISC_R_FAILURE;
if (result == ISC_R_SUCCESS)
return;
reset_probe(trans);
}
开发者ID:jhbsz,项目名称:netbsd,代码行数:81,代码来源:nsprobe.c
示例9: do_scan
static isc_result_t
do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen,
isc_boolean_t verbose)
{
isc_interfaceiter_t *iter = NULL;
isc_boolean_t scan_ipv4 = ISC_FALSE;
isc_boolean_t scan_ipv6 = ISC_FALSE;
isc_boolean_t adjusting = ISC_FALSE;
isc_boolean_t ipv6only = ISC_TRUE;
isc_boolean_t ipv6pktinfo = ISC_TRUE;
isc_result_t result;
isc_netaddr_t zero_address, zero_address6;
ns_listenelt_t *le;
isc_sockaddr_t listen_addr;
ns_interface_t *ifp;
isc_boolean_t log_explicit = ISC_FALSE;
isc_boolean_t dolistenon;
if (ext_listen != NULL)
adjusting = ISC_TRUE;
if (isc_net_probeipv6() == ISC_R_SUCCESS)
scan_ipv6 = ISC_TRUE;
#ifdef WANT_IPV6
else
isc_log_write(IFMGR_COMMON_LOGARGS,
verbose ? ISC_LOG_INFO : ISC_LOG_DEBUG(1),
"no IPv6 interfaces found");
#endif
if (isc_net_probeipv4() == ISC_R_SUCCESS)
scan_ipv4 = ISC_TRUE;
else
isc_log_write(IFMGR_COMMON_LOGARGS,
verbose ? ISC_LOG_INFO : ISC_LOG_DEBUG(1),
"no IPv4 interfaces found");
/*
* A special, but typical case; listen-on-v6 { any; }.
* When we can make the socket IPv6-only, open a single wildcard
* socket for IPv6 communication. Otherwise, make separate socket
* for each IPv6 address in order to avoid accepting IPv4 packets
* as the form of mapped addresses unintentionally unless explicitly
* allowed.
*/
#ifndef ISC_ALLOW_MAPPED
if (scan_ipv6 == ISC_TRUE &&
isc_net_probe_ipv6only() != ISC_R_SUCCESS) {
ipv6only = ISC_FALSE;
log_explicit = ISC_TRUE;
}
#endif
if (scan_ipv6 == ISC_TRUE &&
isc_net_probe_ipv6pktinfo() != ISC_R_SUCCESS) {
ipv6pktinfo = ISC_FALSE;
log_explicit = ISC_TRUE;
}
if (scan_ipv6 == ISC_TRUE && ipv6only && ipv6pktinfo) {
for (le = ISC_LIST_HEAD(mgr->listenon6->elts);
le != NULL;
le = ISC_LIST_NEXT(le, link)) {
struct in6_addr in6a;
if (!listenon_is_ip6_any(le))
continue;
in6a = in6addr_any;
isc_sockaddr_fromin6(&listen_addr, &in6a, le->port);
ifp = find_matching_interface(mgr, &listen_addr);
if (ifp != NULL) {
ifp->generation = mgr->generation;
} else {
isc_log_write(IFMGR_COMMON_LOGARGS,
ISC_LOG_INFO,
"listening on IPv6 "
"interfaces, port %u",
le->port);
result = ns_interface_setup(mgr, &listen_addr,
"<any>", &ifp,
ISC_TRUE);
if (result == ISC_R_SUCCESS)
ifp->flags |= NS_INTERFACEFLAG_ANYADDR;
else
isc_log_write(IFMGR_COMMON_LOGARGS,
ISC_LOG_ERROR,
"listening on all IPv6 "
"interfaces failed");
/* Continue. */
}
}
}
isc_netaddr_any(&zero_address);
isc_netaddr_any6(&zero_address6);
result = isc_interfaceiter_create(mgr->mctx, &iter);
if (result != ISC_R_SUCCESS)
return (result);
//.........这里部分代码省略.........
isc_result_t
dns_ncache_addoptout(dns_message_t *message, dns_db_t *cache,
dns_dbnode_t *node, dns_rdatatype_t covers,
isc_stdtime_t now, dns_ttl_t maxttl,
isc_boolean_t optout, dns_rdataset_t *addedrdataset)
{
isc_result_t result;
isc_buffer_t buffer;
isc_region_t r;
dns_rdataset_t *rdataset;
dns_rdatatype_t type;
dns_name_t *name;
dns_ttl_t ttl;
dns_trust_t trust;
dns_rdata_t rdata[DNS_NCACHE_RDATA];
dns_rdataset_t ncrdataset;
dns_rdatalist_t ncrdatalist;
unsigned char data[4096];
unsigned int next = 0;
/*
* Convert the authority data from 'message' into a negative cache
* rdataset, and store it in 'cache' at 'node'.
*/
REQUIRE(message != NULL);
/*
* We assume that all data in the authority section has been
* validated by the caller.
*/
/*
* Initialize the list.
*/
ncrdatalist.rdclass = dns_db_class(cache);
ncrdatalist.type = 0;
ncrdatalist.covers = covers;
ncrdatalist.ttl = maxttl;
ISC_LIST_INIT(ncrdatalist.rdata);
ISC_LINK_INIT(&ncrdatalist, link);
/*
* Build an ncache rdatas into buffer.
*/
ttl = maxttl;
trust = 0xffff;
isc_buffer_init(&buffer, data, sizeof(data));
if (message->counts[DNS_SECTION_AUTHORITY])
result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
else
result = ISC_R_NOMORE;
while (result == ISC_R_SUCCESS) {
name = NULL;
dns_message_currentname(message, DNS_SECTION_AUTHORITY,
&name);
if ((name->attributes & DNS_NAMEATTR_NCACHE) != 0) {
for (rdataset = ISC_LIST_HEAD(name->list);
rdataset != NULL;
rdataset = ISC_LIST_NEXT(rdataset, link)) {
if ((rdataset->attributes &
DNS_RDATASETATTR_NCACHE) == 0)
continue;
type = rdataset->type;
if (type == dns_rdatatype_rrsig)
type = rdataset->covers;
if (type == dns_rdatatype_soa ||
type == dns_rdatatype_nsec ||
type == dns_rdatatype_nsec3) {
if (ttl > rdataset->ttl)
ttl = rdataset->ttl;
if (trust > rdataset->trust)
trust = rdataset->trust;
/*
* Copy the owner name to the buffer.
*/
dns_name_toregion(name, &r);
result = isc_buffer_copyregion(&buffer,
&r);
if (result != ISC_R_SUCCESS)
return (result);
/*
* Copy the type to the buffer.
*/
isc_buffer_availableregion(&buffer,
&r);
if (r.length < 3)
return (ISC_R_NOSPACE);
isc_buffer_putuint16(&buffer,
rdataset->type);
isc_buffer_putuint8(&buffer,
(unsigned char)rdataset->trust);
/*
* Copy the rdataset into the buffer.
*/
result = copy_rdataset(rdataset,
&buffer);
if (result != ISC_R_SUCCESS)
return (result);
//.........这里部分代码省略.........
static void
update_listener(ns_controls_t *cp, controllistener_t **listenerp,
const cfg_obj_t *control, const cfg_obj_t *config,
isc_sockaddr_t *addr, cfg_aclconfctx_t *aclconfctx,
const char *socktext, isc_sockettype_t type)
{
controllistener_t *listener;
const cfg_obj_t *allow;
const cfg_obj_t *global_keylist = NULL;
const cfg_obj_t *control_keylist = NULL;
dns_acl_t *new_acl = NULL;
controlkeylist_t keys;
isc_result_t result = ISC_R_SUCCESS;
for (listener = ISC_LIST_HEAD(cp->listeners);
listener != NULL;
listener = ISC_LIST_NEXT(listener, link))
if (isc_sockaddr_equal(addr, &listener->address))
break;
if (listener == NULL) {
*listenerp = NULL;
return;
}
/*
* There is already a listener for this sockaddr.
* Update the access list and key information.
*
* First try to deal with the key situation. There are a few
* possibilities:
* (a) It had an explicit keylist and still has an explicit keylist.
* (b) It had an automagic key and now has an explicit keylist.
* (c) It had an explicit keylist and now needs an automagic key.
* (d) It has an automagic key and still needs the automagic key.
*
* (c) and (d) are the annoying ones. The caller needs to know
* that it should use the automagic configuration for key information
* in place of the named.conf configuration.
*
* XXXDCL There is one other hazard that has not been dealt with,
* the problem that if a key change is being caused by a control
* channel reload, then the response will be with the new key
* and not able to be decrypted by the client.
*/
if (control != NULL)
get_key_info(config, control, &global_keylist,
&control_keylist);
if (control_keylist != NULL) {
INSIST(global_keylist != NULL);
ISC_LIST_INIT(keys);
result = controlkeylist_fromcfg(control_keylist,
listener->mctx, &keys);
if (result == ISC_R_SUCCESS) {
free_controlkeylist(&listener->keys, listener->mctx);
listener->keys = keys;
register_keys(control, global_keylist, &listener->keys,
listener->mctx, socktext);
}
} else {
free_controlkeylist(&listener->keys, listener->mctx);
result = get_rndckey(listener->mctx, &listener->keys);
}
if (result != ISC_R_SUCCESS && global_keylist != NULL) {
/*
* This message might be a little misleading since the
* "new keys" might in fact be identical to the old ones,
* but tracking whether they are identical just for the
* sake of avoiding this message would be too much trouble.
*/
if (control != NULL)
cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING,
"couldn't install new keys for "
"command channel %s: %s",
socktext, isc_result_totext(result));
else
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_CONTROL, ISC_LOG_WARNING,
"couldn't install new keys for "
"command channel %s: %s",
socktext, isc_result_totext(result));
}
/*
* Now, keep the old access list unless a new one can be made.
*/
if (control != NULL && type == isc_sockettype_tcp) {
allow = cfg_tuple_get(control, "allow");
result = cfg_acl_fromconfig(allow, config, ns_g_lctx,
aclconfctx, listener->mctx, 0,
&new_acl);
} else {
result = dns_acl_any(listener->mctx, &new_acl);
}
if (result == ISC_R_SUCCESS) {
dns_acl_detach(&listener->acl);
//.........这里部分代码省略.........
请发表评论