[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] Implement hidserv_XX functions; there is still an XXX in di...
- To: or-cvs@freehaven.net
- Subject: [or-cvs] Implement hidserv_XX functions; there is still an XXX in di...
- From: nickm@seul.org (Nick Mathewson)
- Date: Tue, 30 Mar 2004 22:42:58 -0500 (EST)
- Delivered-to: archiver@seul.org
- Delivered-to: or-cvs-outgoing@seul.org
- Delivered-to: or-cvs@seul.org
- Delivery-date: Tue, 30 Mar 2004 22:43:41 -0500
- Reply-to: or-dev@freehaven.net
- Sender: owner-or-cvs@freehaven.net
Update of /home/or/cvsroot/src/or
In directory moria.mit.edu:/tmp/cvs-serv12566/src/or
Modified Files:
directory.c main.c or.h rendcommon.c
Log Message:
Implement hidserv_XX functions; there is still an XXX in directory_handle_command
Index: directory.c
===================================================================
RCS file: /home/or/cvsroot/src/or/directory.c,v
retrieving revision 1.72
retrieving revision 1.73
diff -u -d -r1.72 -r1.73
--- directory.c 30 Mar 2004 23:41:24 -0000 1.72
+++ directory.c 31 Mar 2004 03:42:56 -0000 1.73
@@ -288,11 +288,6 @@
return 0;
}
-/* XXX stubs, probably shouldn't be located here */
-#define MAX_HIDSERV_DESC_SIZE 2048
-int hidserv_lookup(char *query, char *desc, int max_desc_size) { return 0; }
-int hidserv_store(char *desc) { return 0; }
-
static char answer200[] = "HTTP/1.0 200 OK\r\n\r\n";
static char answer400[] = "HTTP/1.0 400 Bad request\r\n\r\n";
static char answer403[] = "HTTP/1.0 403 Unapproved server\r\n\r\n";
@@ -331,12 +326,13 @@
}
if(!strncmp(url,"/hidserv/",9)) { /* hidserv descriptor fetch */
- char desc[MAX_HIDSERV_DESC_SIZE];
+ const char *descp;
+ int desc_len;
- switch(hidserv_lookup(url+9, desc, MAX_HIDSERV_DESC_SIZE)) {
+ switch(hidserv_lookup(url+9, &descp, &desc_len)) {
case 1: /* valid */
connection_write_to_buf(answer200, strlen(answer200), conn);
- connection_write_to_buf(desc, strlen(desc)+1, conn);
+ connection_write_to_buf(descp, desc_len, conn); /* XXXX Contains NULs*/
break;
case 0: /* well-formed but not present */
connection_write_to_buf(answer404, strlen(answer404), conn);
@@ -355,7 +351,8 @@
/* always returns 0 */
static int directory_handle_command_post(connection_t *conn,
- char *headers, char *body) {
+ char *headers, char *body,
+ int body_len) {
const char *cp;
char *url;
@@ -387,7 +384,7 @@
}
if(!strncmp(url,"/hidserv/",9)) { /* hidserv descriptor post */
- if(hidserv_store(body) < 0)
+ if(hidserv_store(body, body_len) < 0)
connection_write_to_buf(answer400, strlen(answer400), conn);
else
connection_write_to_buf(answer200, strlen(answer200), conn);
@@ -420,7 +417,8 @@
if(!strncasecmp(headers,"GET",3))
r = directory_handle_command_get(conn, headers, body);
else if (!strncasecmp(headers,"POST",4))
- r = directory_handle_command_post(conn, headers, body);
+ /* XXXX this takes a length now, and will fail if the body has NULs. */
+ r = directory_handle_command_post(conn, headers, body, strlen(body));
else {
log_fn(LOG_WARN,"Got headers '%s' with unknown command. Closing.", headers);
r = -1;
Index: main.c
===================================================================
RCS file: /home/or/cvsroot/src/or/main.c,v
retrieving revision 1.212
retrieving revision 1.213
diff -u -d -r1.212 -r1.213
--- main.c 30 Mar 2004 22:57:49 -0000 1.212
+++ main.c 31 Mar 2004 03:42:56 -0000 1.213
@@ -334,6 +334,7 @@
/* We're a directory; dump any old descriptors. */
dirserv_remove_old_servers();
}
+ hidserv_cache_clean(); /* should this go elsewhere? */
time_to_fetch_directory = now + options.DirFetchPostPeriod;
}
@@ -547,6 +548,8 @@
/* Initialize the history structures. */
rep_hist_init();
+ /* Intialize the service cache. */
+ hidserv_cache_init();
/* load the private keys, if we're supposed to have them, and set up the
* TLS context. */
Index: or.h
===================================================================
RCS file: /home/or/cvsroot/src/or/or.h,v
retrieving revision 1.263
retrieving revision 1.264
diff -u -d -r1.263 -r1.264
--- or.h 31 Mar 2004 02:04:06 -0000 1.263
+++ or.h 31 Mar 2004 03:42:56 -0000 1.264
@@ -985,6 +985,12 @@
char **str_out,
int *len_out);
rend_service_descriptor_t *rend_parse_service_descriptor(const char *str, int len);
+int rend_get_service_id(crypto_pk_env_t *pk, char *out);
+
+void hidserv_cache_init(void);
+void hidserv_cache_clean(void);
+int hidserv_lookup(char *query, const char **desc, int *desc_len);
+int hidserv_store(char *desc, int desc_len);
#endif
Index: rendcommon.c
===================================================================
RCS file: /home/or/cvsroot/src/or/rendcommon.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- rendcommon.c 31 Mar 2004 02:07:38 -0000 1.1
+++ rendcommon.c 31 Mar 2004 03:42:56 -0000 1.2
@@ -67,7 +67,6 @@
return 0;
}
-
rend_service_descriptor_t *rend_parse_service_descriptor(
const char *str, int len)
{
@@ -128,3 +127,121 @@
return NULL;
}
+int rend_get_service_id(crypto_pk_env_t *pk, char *out)
+{
+ char buf[CRYPTO_SHA1_DIGEST_LEN];
+ assert(pk);
+ if (crypto_pk_get_digest(pk, buf) < 0)
+ return -1;
+ if (base32_encode(out, REND_SERVICE_ID_LEN+1, buf, 10) < 0)
+ return -1;
+ return 0;
+}
+
+/* ==== Hidden service descriptor cache. */
+#define HIDSERV_MAX_AGE 24*60*60
+#define HIDSERV_MAX_SKEW 60*60
+
+typedef struct hidserv_cache_entry_t {
+ int len;
+ char *desc;
+ rend_service_descriptor_t *parsed;
+} hidserv_cache_entry_t;
+
+static strmap_t *hidserv_cache = NULL;
+
+void hidserv_cache_init(void)
+{
+ hidserv_cache = strmap_new();
+}
+
+void hidserv_cache_clean(void)
+{
+ strmap_iter_t *iter;
+ const char *key;
+ void *val;
+ hidserv_cache_entry_t *ent;
+ time_t cutoff;
+ cutoff = time(NULL) - HIDSERV_MAX_AGE;
+ for (iter = strmap_iter_init(hidserv_cache); !strmap_iter_done(iter); ) {
+ strmap_iter_get(iter, &key, &val);
+ ent = (hidserv_cache_entry_t*)val;
+ if (ent->parsed->timestamp < cutoff) {
+ iter = strmap_iter_next_rmv(hidserv_cache, iter);
+ rend_service_descriptor_free(ent->parsed);
+ tor_free(ent->desc);
+ tor_free(ent);
+ } else {
+ iter = strmap_iter_next(hidserv_cache, iter);
+ }
+ }
+}
+
+int hidserv_lookup(char *query, const char **desc, int *desc_len)
+{
+ hidserv_cache_entry_t *e;
+ assert(hidserv_cache);
+ if (strlen(query) != REND_SERVICE_ID_LEN)
+ return -1; /* XXXX also check for bad chars. */
+ e = (hidserv_cache_entry_t*) strmap_get_lc(hidserv_cache, query);
+ if (!e)
+ return 0;
+ *desc = e->desc;
+ *desc_len = e->len;
+ return 1;
+}
+
+int hidserv_store(char *desc, int desc_len)
+{
+ hidserv_cache_entry_t *e;
+ rend_service_descriptor_t *parsed;
+ char query[REND_SERVICE_ID_LEN+1];
+ time_t now;
+ assert(hidserv_cache);
+ parsed = rend_parse_service_descriptor(desc,desc_len);
+ if (!parsed) {
+ log_fn(LOG_WARN,"Couldn't parse service descriptor");
+ return -1;
+ }
+ if (rend_get_service_id(parsed->pk, query)<0) {
+ log_fn(LOG_WARN,"Couldn't compute service ID");
+ rend_service_descriptor_free(parsed);
+ return -1;
+ }
+ now = time(NULL);
+ if (parsed->timestamp < now-HIDSERV_MAX_AGE) {
+ log_fn(LOG_WARN,"Service descriptor is too old");
+ rend_service_descriptor_free(parsed);
+ return -1;
+ }
+ if (parsed->timestamp > now+HIDSERV_MAX_SKEW) {
+ log_fn(LOG_WARN,"Service descriptor is too far in the future");
+ rend_service_descriptor_free(parsed);
+ return -1;
+ }
+ e = (hidserv_cache_entry_t*) strmap_get_lc(hidserv_cache, query);
+ if (e && e->parsed->timestamp > parsed->timestamp) {
+ log_fn(LOG_WARN,"We already have a newer service descriptor with the same ID");
+ rend_service_descriptor_free(parsed);
+ return -1;
+ }
+ if (e && e->len == desc_len && !memcmp(desc,e->desc,desc_len)) {
+ log_fn(LOG_WARN,"We already have this service descriptor");
+ rend_service_descriptor_free(parsed);
+ return -1;
+ }
+ if (!e) {
+ e = tor_malloc_zero(sizeof(hidserv_cache_entry_t));
+ strmap_set_lc(hidserv_cache, query, e);
+ } else {
+ rend_service_descriptor_free(e->parsed);
+ tor_free(e->desc);
+ }
+ e->parsed = parsed;
+ e->len = desc_len;
+ e->desc = tor_strdup(desc);
+
+ return 0;
+}
+
+