[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] Add TTLs to RESOLVED, CONNECTED, and END_REASON_EXITPOLICY ...



Update of /home/or/cvsroot/tor/src/or
In directory moria:/tmp/cvs-serv6452/src/or

Modified Files:
	relay.c dns.c connection_edge.c 
Log Message:
Add TTLs to RESOLVED, CONNECTED, and END_REASON_EXITPOLICY cells.  Also, add a missing ntohl in connection_ap_handshake_socks_resolved.

Index: relay.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/relay.c,v
retrieving revision 1.77
retrieving revision 1.78
diff -u -d -r1.77 -r1.78
--- relay.c	15 Aug 2005 03:35:15 -0000	1.77
+++ relay.c	2 Sep 2005 18:53:31 -0000	1.78
@@ -640,14 +640,19 @@
       case END_STREAM_REASON_EXITPOLICY:
         if (rh->length >= 5) {
           uint32_t addr = ntohl(get_uint32(cell->payload+RELAY_HEADER_SIZE+1));
+          int ttl;
           if (!addr) {
             log_fn(LOG_INFO,"Address '%s' resolved to 0.0.0.0. Closing,",
                    safe_str(conn->socks_request->address));
             connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
             return 0;
           }
+          if (rh->length >= 9)
+            ttl = (int)ntohl(get_uint32(cell->payload+RELAY_HEADER_SIZE+5));
+          else
+            ttl = -1;
           client_dns_set_addressmap(conn->socks_request->address, addr,
-                                    conn->chosen_exit_name);
+                                    conn->chosen_exit_name, ttl);
         }
         /* check if he *ought* to have allowed it */
         if (exitrouter &&
@@ -735,14 +740,19 @@
            (int)(time(NULL) - conn->timestamp_lastread));
     if (rh->length >= 4) {
       uint32_t addr = ntohl(get_uint32(cell->payload+RELAY_HEADER_SIZE));
+      int ttl;
       if (!addr) {
         log_fn(LOG_INFO,"...but it claims the IP address was 0.0.0.0. Closing.");
         connection_edge_end(conn, END_STREAM_REASON_TORPROTOCOL, conn->cpath_layer);
         connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
         return 0;
       }
+      if (rh->length >= 8)
+        ttl = (int)ntohl(get_uint32(cell->payload+RELAY_HEADER_SIZE+8));
+      else
+        ttl = -1;
       client_dns_set_addressmap(conn->socks_request->address, addr,
-                                conn->chosen_exit_name);
+                                conn->chosen_exit_name, ttl);
     }
     circuit_log_path(LOG_INFO,circ);
     connection_ap_handshake_socks_reply(conn, NULL, 0, SOCKS5_SUCCEEDED);
@@ -755,20 +765,28 @@
     return 0;
   }
   if (conn->type == CONN_TYPE_AP && rh->command == RELAY_COMMAND_RESOLVED) {
+    int ttl;
+    int answer_len;
     if (conn->state != AP_CONN_STATE_RESOLVE_WAIT) {
       log_fn(LOG_WARN,"Got a 'resolved' cell while not in state resolve_wait. Dropping.");
       return 0;
     }
     tor_assert(conn->socks_request->command == SOCKS_COMMAND_RESOLVE);
-    if (rh->length < 2 || cell->payload[RELAY_HEADER_SIZE+1]+2>rh->length) {
+    answer_len = cell->payload[RELAY_HEADER_SIZE+1];
+    if (rh->length < 2 || answer_len+2>rh->length) {
       log_fn(LOG_WARN, "Dropping malformed 'resolved' cell");
       connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
       return 0;
     }
+    if (rh->length >= answer_len+6)
+      ttl = (int)ntohl(get_uint32(cell->payload+RELAY_HEADER_SIZE+6));
+    else
+      ttl = -1;
     connection_ap_handshake_socks_resolved(conn,
                    cell->payload[RELAY_HEADER_SIZE], /*answer_type*/
                    cell->payload[RELAY_HEADER_SIZE+1], /*answer_len*/
-                   cell->payload+RELAY_HEADER_SIZE+2); /* answer */
+                   cell->payload+RELAY_HEADER_SIZE+2,
+                   ttl); /* answer */
     connection_mark_unattached_ap(conn, END_STREAM_REASON_ALREADY_SOCKS_REPLIED);
     return 0;
   }

Index: dns.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/dns.c,v
retrieving revision 1.165
retrieving revision 1.166
diff -u -d -r1.165 -r1.166
--- dns.c	15 Aug 2005 23:46:18 -0000	1.165
+++ dns.c	2 Sep 2005 18:53:31 -0000	1.166
@@ -192,14 +192,21 @@
     case RESOLVED_TYPE_IPV4:
       buf[1] = 4;
       set_uint32(buf+2, htonl(conn->addr));
-      buflen = 6;
+      set_uint32(buf+6, htonl(MAX_DNS_ENTRY_AGE)); /*XXXX send a real TTL*/
+      buflen = 10;
       break;
     case RESOLVED_TYPE_ERROR_TRANSIENT:
     case RESOLVED_TYPE_ERROR:
-      buf[1] = 24; /* length of "error resolving hostname" */
-      strlcpy(buf+2, "error resolving hostname", sizeof(buf)-2);
-      buflen = 26;
-      break;
+      {
+        const char *errmsg = "Error resolving hostname";
+        int msglen = strlen(errmsg);
+        int ttl = (answer_type == RESOLVED_TYPE_ERROR ? MAX_DNS_ENTRY_AGE : 0);
+        buf[1] = msglen;
+        strlcpy(buf+2, errmsg, sizeof(buf)-2);
+        set_uint32(buf+2+msglen, htonl((uint32_t)ttl));
+        buflen = 6+msglen;
+        break;
+      }
     default:
       tor_assert(0);
     }

Index: connection_edge.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/connection_edge.c,v
retrieving revision 1.342
retrieving revision 1.343
diff -u -d -r1.342 -r1.343
--- connection_edge.c	22 Aug 2005 00:34:42 -0000	1.342
+++ connection_edge.c	2 Sep 2005 18:53:31 -0000	1.343
@@ -48,7 +48,7 @@
     if (conn->socks_request->command == SOCKS_COMMAND_CONNECT)
       connection_ap_handshake_socks_reply(conn, NULL, 0, socksreason);
     else
-      connection_ap_handshake_socks_resolved(conn,RESOLVED_TYPE_ERROR,0,NULL);
+      connection_ap_handshake_socks_resolved(conn,RESOLVED_TYPE_ERROR,0,NULL,-1);
   }
 
   _connection_mark_for_close(conn, line, file);
@@ -194,7 +194,8 @@
     /* this is safe even for rend circs, because they never fail
      * because of exitpolicy */
     set_uint32(payload+1, htonl(conn->addr));
-    payload_len += 4;
+    set_uint32(payload+5, htonl(MAX_DNS_ENTRY_AGE)); /* XXXXfill with a real TTL*/
+    payload_len += 8;
   }
 
   circ = circuit_get_by_edge_conn(conn);
@@ -266,7 +267,6 @@
 int
 connection_edge_finished_connecting(connection_t *conn)
 {
-  char connected_payload[4];
   char valbuf[INET_NTOA_BUF_LEN];
   struct in_addr in;
 
@@ -289,9 +289,12 @@
                                      RELAY_COMMAND_CONNECTED, NULL, 0, conn->cpath_layer) < 0)
       return 0; /* circuit is closed, don't continue */
   } else {
-    *(uint32_t*)connected_payload = htonl(conn->addr);
+    char connected_payload[8];
+    set_uint32(connected_payload, htonl(htonl(conn->addr)));
+    set_uint32(connected_payload+4,
+               htonl(MAX_DNS_ENTRY_AGE)); /* XXXX fill with a real TTL */
     if (connection_edge_send_command(conn, circuit_get_by_edge_conn(conn),
-        RELAY_COMMAND_CONNECTED, connected_payload, 4, conn->cpath_layer) < 0)
+        RELAY_COMMAND_CONNECTED, connected_payload, 8, conn->cpath_layer) < 0)
       return 0; /* circuit is closed, don't continue */
   }
   tor_assert(conn->package_window > 0);
@@ -683,9 +686,13 @@
  *
  * If <b>exitname</b> is defined, then append the addresses with
  * ".exitname.exit" before registering the mapping.
+ *
+ * If <b>ttl</b> is nonnegative, the mapping will be valid for
+ * <b>ttl</b>seconds.
  */
 void
-client_dns_set_addressmap(const char *address, uint32_t val, const char *exitname)
+client_dns_set_addressmap(const char *address, uint32_t val, const char *exitname,
+                          int ttl)
 {
   struct in_addr in;
   char extendedaddress[MAX_SOCKS_ADDR_LEN+MAX_HEX_NICKNAME_LEN+10];
@@ -694,6 +701,9 @@
 
   tor_assert(address); tor_assert(val);
 
+  if (ttl<0 || ttl>MAX_DNS_ENTRY_AGE)
+    ttl = MAX_DNS_ENTRY_AGE;
+
   if (tor_inet_aton(address, &in))
     return; /* If address was an IP address already, don't add a mapping. */
   in.s_addr = htonl(val);
@@ -709,8 +719,7 @@
     tor_snprintf(extendedval, sizeof(extendedval),
                  "%s", valbuf);
   }
-  addressmap_register(extendedaddress, tor_strdup(extendedval),
-                      time(NULL) + MAX_DNS_ENTRY_AGE);
+  addressmap_register(extendedaddress, tor_strdup(extendedval), time(NULL) + ttl);
 }
 
 /* Currently, we hand out 127.192.0.1 through 127.254.254.254.
@@ -1019,14 +1028,14 @@
       /* Reply to resolves immediately if we can. */
       if (strlen(socks->address) > RELAY_PAYLOAD_SIZE) {
         log_fn(LOG_WARN,"Address to be resolved is too large. Failing.");
-        connection_ap_handshake_socks_resolved(conn,RESOLVED_TYPE_ERROR,0,NULL);
+        connection_ap_handshake_socks_resolved(conn,RESOLVED_TYPE_ERROR,0,NULL,-1);
         connection_mark_unattached_ap(conn, END_STREAM_REASON_ALREADY_SOCKS_REPLIED);
         return -1;
       }
       if (tor_inet_aton(socks->address, &in)) { /* see if it's an IP already */
         answer = in.s_addr; /* leave it in network order */
         connection_ap_handshake_socks_resolved(conn,RESOLVED_TYPE_IPV4,4,
-                                               (char*)&answer);
+                                               (char*)&answer,-1);
         connection_mark_unattached_ap(conn, END_STREAM_REASON_ALREADY_SOCKS_REPLIED);
         return 0;
       }
@@ -1075,7 +1084,7 @@
       /* if it's a resolve request, fail it right now, rather than
        * building all the circuits and then realizing it won't work. */
       log_fn(LOG_WARN,"Resolve requests to hidden services not allowed. Failing.");
-      connection_ap_handshake_socks_resolved(conn,RESOLVED_TYPE_ERROR,0,NULL);
+      connection_ap_handshake_socks_resolved(conn,RESOLVED_TYPE_ERROR,0,NULL,-1);
       connection_mark_unattached_ap(conn, END_STREAM_REASON_ALREADY_SOCKS_REPLIED);
       return -1;
     }
@@ -1299,16 +1308,17 @@
 connection_ap_handshake_socks_resolved(connection_t *conn,
                                        int answer_type,
                                        size_t answer_len,
-                                       const char *answer)
+                                       const char *answer,
+                                       int ttl)
 {
   char buf[256];
   size_t replylen;
 
   if (answer_type == RESOLVED_TYPE_IPV4) {
-    uint32_t a = get_uint32(answer);
+    uint32_t a = ntohl(get_uint32(answer));
     if (a)
       client_dns_set_addressmap(conn->socks_request->address, ntohl(a),
-                                conn->chosen_exit_name);
+                                conn->chosen_exit_name, ttl);
   }
 
   if (conn->socks_request->socks_version == 4) {
@@ -1581,7 +1591,6 @@
 void
 connection_exit_connect(connection_t *conn)
 {
-  char connected_payload[4];
   uint32_t addr;
   uint16_t port;
 
@@ -1649,10 +1658,13 @@
                                  NULL, 0, conn->cpath_layer);
   } else { /* normal stream */
     /* This must be the original address, not the redirected address. */
-    *(uint32_t*)connected_payload = htonl(conn->addr);
+    char connected_payload[8];
+    set_uint32(connected_payload, htonl(htonl(conn->addr)));
+    set_uint32(connected_payload+4,
+               htonl(MAX_DNS_ENTRY_AGE)); /* XXXX fill with a real TTL */
     connection_edge_send_command(conn, circuit_get_by_edge_conn(conn),
                                  RELAY_COMMAND_CONNECTED,
-                                 connected_payload, 4, conn->cpath_layer);
+                                 connected_payload, 8, conn->cpath_layer);
   }
 }