Commit d050ff79 authored by Roger Dingledine's avatar Roger Dingledine
Browse files

resolve lucky's recent bug: tor was exiting if we failed to spawn

a new dns worker (e.g. because we were out of fd's).


svn:r5112
parent 2d6b36a0
Loading
Loading
Loading
Loading
+17 −9
Original line number Diff line number Diff line
@@ -73,7 +73,7 @@ static void dns_purge_resolve(cached_resolve_t *resolve);
static void dns_found_answer(char *address, uint32_t addr, char outcome);
static int dnsworker_main(void *data);
static int spawn_dnsworker(void);
static void spawn_enough_dnsworkers(void);
static int spawn_enough_dnsworkers(void);
static void send_resolved_cell(connection_t *conn, uint8_t answer_type);

/** Splay tree of cached_resolve objects. */
@@ -334,7 +334,10 @@ assign_to_dnsworker(connection_t *exitconn)
  tor_assert(exitconn->state == EXIT_CONN_STATE_RESOLVING);
  tor_assert(exitconn->s == -1);

  spawn_enough_dnsworkers(); /* respawn here, to be sure there are enough */
  /* respawn here, to be sure there are enough */
  if (spawn_enough_dnsworkers() < 0) {
    goto err;
  }

  dnsconn = connection_get_by_type_state(CONN_TYPE_DNSWORKER, DNSWORKER_STATE_IDLE);

@@ -342,8 +345,7 @@ assign_to_dnsworker(connection_t *exitconn)
    log_fn(LOG_WARN,"no idle dns workers. Failing.");
    if (exitconn->purpose == EXIT_PURPOSE_RESOLVE)
      send_resolved_cell(exitconn, RESOLVED_TYPE_ERROR_TRANSIENT);
    dns_cancel_pending_resolve(exitconn->address); /* also sends end and frees! */
    return -1;
    goto err;
  }

  log_fn(LOG_DEBUG, "Connection (fd %d) needs to resolve '%s'; assigning to DNSWorker (fd %d)",
@@ -359,6 +361,9 @@ assign_to_dnsworker(connection_t *exitconn)
  connection_write_to_buf(dnsconn->address, len, dnsconn);

  return 0;
err:
  dns_cancel_pending_resolve(exitconn->address); /* also sends end and frees! */
  return -1;
}

/** Remove <b>conn</b> from the list of connections waiting for conn-\>address.
@@ -834,10 +839,9 @@ spawn_dnsworker(void)

  fdarray = tor_malloc(sizeof(int)*2);
  if ((err = tor_socketpair(AF_UNIX, SOCK_STREAM, 0, fdarray)) < 0) {
    log(LOG_ERR, "Couldn't construct socketpair: %s", tor_socket_strerror(-err));
    tor_cleanup();
    log(LOG_WARN, "Couldn't construct socketpair: %s", tor_socket_strerror(-err));
    tor_free(fdarray);
    exit(1);
    return -1;
  }

  /* log_fn(LOG_NOTICE,"Before spawn: fdarray @%d has %d:%d", (int)fdarray, fdarray[0],fdarray[1]); */
@@ -871,8 +875,10 @@ spawn_dnsworker(void)
}

/** If we have too many or too few DNS workers, spawn or kill some.
 * Return 0 if we are happy, return -1 if we tried to spawn more but
 * we couldn't.
 */
static void
static int
spawn_enough_dnsworkers(void)
{
  int num_dnsworkers_needed; /* aim to have 1 more than needed,
@@ -911,7 +917,7 @@ spawn_enough_dnsworkers(void)
  while (num_dnsworkers < num_dnsworkers_needed) {
    if (spawn_dnsworker() < 0) {
      log_fn(LOG_WARN,"spawn failed!");
      return;
      return -1;
    }
    num_dnsworkers++;
  }
@@ -926,5 +932,7 @@ spawn_enough_dnsworkers(void)
    connection_mark_for_close(dnsconn);
    num_dnsworkers--;
  }

  return 0;
}