Ejemplo n.º 1
0
Archivo: res_libc.c Proyecto: dreal/tai
/* Initialize resp if RES_INIT is not yet set or if res_init in some other
   thread requested re-initializing.  */
int
__res_maybe_init (res_state resp, int preinit)
{
	static time_t last_mtime;
	struct stat statbuf;
	int ret;

	if (resp->options & RES_INIT) {
		ret = stat (_PATH_RESCONF, &statbuf);
		__libc_lock_lock (lock);
		if ((ret == 0) && (last_mtime != statbuf.st_mtime)) {
			last_mtime = statbuf.st_mtime;
			atomicinc (__res_initstamp);
		}
		__libc_lock_unlock (lock);
		if (__res_initstamp != resp->_u._ext.initstamp) {
			if (resp->nscount > 0)
				__res_iclose (resp, true);
			return __res_vinit (resp, 1);
		}
		return 0;
	} else if (preinit) {
		if (!resp->retrans)
			resp->retrans = RES_TIMEOUT;
		if (!resp->retry)
			resp->retry = 4;
		resp->options = RES_DEFAULT;
		if (!resp->id)
			resp->id = res_randomid ();
		return __res_vinit (resp, 1);
	} else
		return __res_ninit (resp);
}
Ejemplo n.º 2
0
/* Initialize *RESP if RES_INIT is not yet set in RESP->options, or if
   res_init in some other thread requested re-initializing.  */
static __attribute__ ((warn_unused_result)) bool
maybe_init (struct resolv_context *ctx, bool preinit)
{
  struct __res_state *resp = ctx->resp;
  if (resp->options & RES_INIT)
    {
      if (resp->options & RES_NORELOAD)
        /* Configuration reloading was explicitly disabled.  */
        return true;

      /* If there is no associated resolv_conf object despite the
         initialization, something modified *ctx->resp.  Do not
         override those changes.  */
      if (ctx->conf != NULL && replicated_configuration_matches (ctx))
        {
          struct resolv_conf *current = __resolv_conf_get_current ();
          if (current == NULL)
            return false;

          /* Check if the configuration changed.  */
          if (current != ctx->conf)
            {
              /* This call will detach the extended resolver state.  */
              if (resp->nscount > 0)
                __res_iclose (resp, true);
              /* Reattach the current configuration.  */
              if (__resolv_conf_attach (ctx->resp, current))
                {
                  __resolv_conf_put (ctx->conf);
                  /* ctx takes ownership, so we do not release current.  */
                  ctx->conf = current;
                }
            }
          else
            /* No change.  Drop the reference count for current.  */
            __resolv_conf_put (current);
        }
      return true;
    }

  assert (ctx->conf == NULL);
  if (preinit)
    {
      if (!resp->retrans)
        resp->retrans = RES_TIMEOUT;
      if (!resp->retry)
        resp->retry = RES_DFLRETRY;
      resp->options = RES_DEFAULT;
      if (!resp->id)
        resp->id = res_randomid ();
    }

  if (__res_vinit (resp, preinit) < 0)
    return false;
  ctx->conf = __resolv_conf_get (ctx->resp);
  return true;
}
Ejemplo n.º 3
0
/* This function belongs to libresolv, which is why it is not included
   in res-close.c.  */
void
__res_close (void)
{
  /* Some programs call res_close before res_init.  Since _res._vcsock
     isn't explicitly initialized, these means that we could call
     close (0), which might lead to some security problems.  Therefore
     we check if res_init was called before by looking at the RES_INIT
     bit in _res.options.  If it hasn't been set we bail out
     early.  */
  if ((_res.options & RES_INIT) == 0)
    return;
  /* We don't free the name server addresses because we never did it
     and it would be done implicitly on shutdown.  */
  __res_iclose (&_res, false);
}
Ejemplo n.º 4
0
int
res_init(void) {
	extern int __res_vinit(res_state, int);

	/*
	 * These three fields used to be statically initialized.  This made
	 * it hard to use this code in a shared library.  It is necessary,
	 * now that we're doing dynamic initialization here, that we preserve
	 * the old semantics: if an application modifies one of these three
	 * fields of _res before res_init() is called, res_init() will not
	 * alter them.  Of course, if an application is setting them to
	 * _zero_ before calling res_init(), hoping to override what used
	 * to be the static default, we can't detect it and unexpected results
	 * will follow.  Zero for any of these fields would make no sense,
	 * so one can safely assume that the applications were already getting
	 * unexpected results.
	 *
	 * _res.options is tricky since some apps were known to diddle the bits
	 * before res_init() was first called. We can't replicate that semantic
	 * with dynamic initialization (they may have turned bits off that are
	 * set in RES_DEFAULT).  Our solution is to declare such applications
	 * "broken".  They could fool us by setting RES_INIT but none do (yet).
	 */
	if (!_res.retrans)
		_res.retrans = RES_TIMEOUT;
	if (!_res.retry)
		_res.retry = 4;
	if (!(_res.options & RES_INIT))
		_res.options = RES_DEFAULT;
	else if (_res.nscount > 0)
		__res_iclose (&_res, true);	/* Close any VC sockets.  */

	/*
	 * This one used to initialize implicitly to zero, so unless the app
	 * has set it to something in particular, we can randomize it now.
	 */
	if (!_res.id)
		_res.id = res_randomid();

	atomicinclock (lock);
	/* Request all threads to re-initialize their resolver states,
	   resolv.conf might have changed.  */
	atomicinc (__res_initstamp);
	atomicincunlock (lock);

	return (__res_vinit(&_res, 1));
}
Ejemplo n.º 5
0
/* Initialize resp if RES_INIT is not yet set or if res_init in some other
   thread requested re-initializing.  */
int
__res_maybe_init (res_state resp, int preinit)
{
	if (resp->options & RES_INIT) {
		if (__res_initstamp != resp->_u._ext.initstamp) {
			if (resp->nscount > 0)
				__res_iclose (resp, true);
			return __res_vinit (resp, 1);
		}
		return 0;
	} else if (preinit) {
		if (!resp->retrans)
			resp->retrans = RES_TIMEOUT;
		if (!resp->retry)
			resp->retry = 4;
		resp->options = RES_DEFAULT;
		if (!resp->id)
			resp->id = res_randomid ();
		return __res_vinit (resp, 1);
	} else
		return __res_ninit (resp);
}