Back to index

tor  0.2.3.18-rc
Functions
dnsserv.h File Reference

Header file for dnsserv.c. More...

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void dnsserv_configure_listener (connection_t *conn)
 Set up the evdns server port for the UDP socket on conn, which must be an AP_DNS_LISTENER.
void dnsserv_close_listener (connection_t *conn)
 Free the evdns server port for conn, which must be an AP_DNS_LISTENER.
void dnsserv_resolved (entry_connection_t *conn, int answer_type, size_t answer_len, const char *answer, int ttl)
 Tell the dns request waiting for an answer on conn that we have an answer of type answer_type (RESOLVE_TYPE_IPV4/IPV6/ERR), of length answer_len, in answer, with TTL ttl.
void dnsserv_reject_request (entry_connection_t *conn)
 If there is a pending request on conn that's waiting for an answer, send back an error and free the request.
int dnsserv_launch_request (const char *name, int is_reverse)
 Helper function: called whenever the client sends a resolve request to our controller.

Detailed Description

Header file for dnsserv.c.

Definition in file dnsserv.h.


Function Documentation

Free the evdns server port for conn, which must be an AP_DNS_LISTENER.

Definition at line 337 of file dnsserv.c.

{
  listener_connection_t *listener_conn;
  tor_assert(conn);
  tor_assert(conn->type == CONN_TYPE_AP_DNS_LISTENER);

  listener_conn = TO_LISTENER_CONN(conn);

  if (listener_conn->dns_server_port) {
    evdns_close_server_port(listener_conn->dns_server_port);
    listener_conn->dns_server_port = NULL;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Set up the evdns server port for the UDP socket on conn, which must be an AP_DNS_LISTENER.

Definition at line 321 of file dnsserv.c.

{
  listener_connection_t *listener_conn;
  tor_assert(conn);
  tor_assert(SOCKET_OK(conn->s));
  tor_assert(conn->type == CONN_TYPE_AP_DNS_LISTENER);

  listener_conn = TO_LISTENER_CONN(conn);
  listener_conn->dns_server_port =
    tor_evdns_add_server_port(conn->s, 0, evdns_server_callback,
                              listener_conn);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int dnsserv_launch_request ( const char *  name,
int  reverse 
)

Helper function: called whenever the client sends a resolve request to our controller.

We need to eventually answer the request req. Returns 0 if the controller will be getting (or has gotten) an event in response; -1 if we couldn't launch the request.

Definition at line 172 of file dnsserv.c.

{
  entry_connection_t *entry_conn;
  edge_connection_t *conn;
  char *q_name;

  /* Make a new dummy AP connection, and attach the request to it. */
  entry_conn = entry_connection_new(CONN_TYPE_AP, AF_INET);
  conn = ENTRY_TO_EDGE_CONN(entry_conn);
  conn->_base.state = AP_CONN_STATE_RESOLVE_WAIT;

  if (reverse)
    entry_conn->socks_request->command = SOCKS_COMMAND_RESOLVE_PTR;
  else
    entry_conn->socks_request->command = SOCKS_COMMAND_RESOLVE;

  conn->is_dns_request = 1;

  strlcpy(entry_conn->socks_request->address, name,
          sizeof(entry_conn->socks_request->address));

  entry_conn->socks_request->listener_type = CONN_TYPE_CONTROL_LISTENER;
  entry_conn->original_dest_address = tor_strdup(name);
  entry_conn->session_group = SESSION_GROUP_CONTROL_RESOLVE;
  entry_conn->nym_epoch = get_signewnym_epoch();
  entry_conn->isolation_flags = ISO_DEFAULT;

  if (connection_add(TO_CONN(conn))<0) {
    log_warn(LD_APP, "Couldn't register dummy connection for RESOLVE request");
    connection_free(TO_CONN(conn));
    return -1;
  }

  /* Now, unless a controller asked us to leave streams unattached,
  * throw the connection over to get rewritten (which will
  * answer it immediately if it's in the cache, or completely bogus, or
  * automapped), and then attached to a circuit. */
  log_info(LD_APP, "Passing request for %s to rewrite_and_attach.",
           escaped_safe_str_client(name));
  q_name = tor_strdup(name); /* q could be freed in rewrite_and_attach */
  connection_ap_rewrite_and_attach_if_allowed(entry_conn, NULL, NULL);
  /* Now, the connection is marked if it was bad. */

  log_info(LD_APP, "Passed request for %s to rewrite_and_attach_if_allowed.",
           escaped_safe_str_client(q_name));
  tor_free(q_name);
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

If there is a pending request on conn that's waiting for an answer, send back an error and free the request.

Definition at line 224 of file dnsserv.c.

Here is the call graph for this function:

Here is the caller graph for this function:

void dnsserv_resolved ( entry_connection_t conn,
int  answer_type,
size_t  answer_len,
const char *  answer,
int  ttl 
)

Tell the dns request waiting for an answer on conn that we have an answer of type answer_type (RESOLVE_TYPE_IPV4/IPV6/ERR), of length answer_len, in answer, with TTL ttl.

Doesn't do any caching; that's handled elsewhere.

Definition at line 270 of file dnsserv.c.

{
  struct evdns_server_request *req = conn->dns_server_request;
  const char *name;
  int err = DNS_ERR_NONE;
  if (!req)
    return;
  name = evdns_get_orig_address(req, answer_type,
                                conn->socks_request->address);

  /* XXXX Re-do; this is dumb. */
  if (ttl < 60)
    ttl = 60;

  /* The evdns interface is: add a bunch of reply items (corresponding to one
   * or more of the questions in the request); then, call
   * evdns_server_request_respond. */
  if (answer_type == RESOLVED_TYPE_IPV6) {
    log_info(LD_APP, "Got an IPv6 answer; that's not implemented.");
    err = DNS_ERR_NOTIMPL;
  } else if (answer_type == RESOLVED_TYPE_IPV4 && answer_len == 4 &&
             conn->socks_request->command == SOCKS_COMMAND_RESOLVE) {
    evdns_server_request_add_a_reply(req,
                                     name,
                                     1, answer, ttl);
  } else if (answer_type == RESOLVED_TYPE_HOSTNAME &&
             answer_len < 256 &&
             conn->socks_request->command == SOCKS_COMMAND_RESOLVE_PTR) {
    char *ans = tor_strndup(answer, answer_len);
    evdns_server_request_add_ptr_reply(req, NULL,
                                       name,
                                       ans, ttl);
    tor_free(ans);
  } else if (answer_type == RESOLVED_TYPE_ERROR) {
    err = DNS_ERR_NOTEXIST;
  } else { /* answer_type == RESOLVED_TYPE_ERROR_TRANSIENT */
    err = DNS_ERR_SERVERFAILED;
  }

  evdns_server_request_respond(req, err);

  conn->dns_server_request = NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function: