summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/or/connection_edge.c2
-rw-r--r--src/or/or.h19
-rw-r--r--src/or/rendcommon.c7
-rw-r--r--src/or/rendmid.c16
-rw-r--r--src/or/rendservice.c69
5 files changed, 86 insertions, 27 deletions
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index 206f5dae7d..04bf1794f0 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -439,6 +439,8 @@ int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
case RELAY_COMMAND_INTRODUCE2:
case RELAY_COMMAND_RENDEZVOUS1:
case RELAY_COMMAND_RENDEZVOUS2:
+ case RELAY_COMMAND_INTRO_ESTABLISHED:
+ case RELAY_COMMAND_RENDEZVOUS_ESTABLISHED:
rend_process_relay_cell(circ, rh.command, rh.length,
cell->payload+RELAY_HEADER_SIZE);
return 0;
diff --git a/src/or/or.h b/src/or/or.h
index ed82140344..11563475a1 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -201,12 +201,15 @@
#define CIRCUIT_PURPOSE_REND_ESTABLISHED 4 /* At OR, both circuits have this purpose */
/* these circuits originate at this node */
#define CIRCUIT_PURPOSE_C_GENERAL 5 /* normal circuit, with cpath */
-#define CIRCUIT_PURPOSE_S_ESTABLISH_INTRO 6 /* at Bob, waiting for introductions */
-#define CIRCUIT_PURPOSE_C_INTRODUCING 7 /* at Alice, connecting to intro point */
-#define CIRCUIT_PURPOSE_C_ESTABLISH_REND 8 /* at Alice, waiting for Bob */
-#define CIRCUIT_PURPOSE_S_CONNECT_REND 9 /* at Bob, connecting to rend point */
-#define CIRCUIT_PURPOSE_C_REND_JOINED 10 /* at Alice, rendezvous established.*/
-#define CIRCUIT_PURPOSE_S_REND_JOINED 11 /* at Bob, rendezvous established.*/
+#define CIRCUIT_PURPOSE_C_INTRODUCING 6 /* at Alice, connecting to intro point */
+#define CIRCUIT_PURPOSE_C_ESTABLISH_REND 7 /* at Alice, waiting for Bob */
+#define CIRCUIT_PURPOSE_C_REND_JOINED 8 /* at Alice, rendezvous established.*/
+
+#define CIRCUIT_PURPOSE_S_ESTABLISH_INTRO 9 /* at Bob, waiting for introductions */
+#define CIRCUIT_PURPOSE_S_INTRO 10 /* at Bob, successfully established intro */
+#define CIRCUIT_PURPOSE_S_CONNECT_REND 11 /* at Bob, connecting to rend point */
+
+#define CIRCUIT_PURPOSE_S_REND_JOINED 12 /* at Bob, rendezvous established.*/
#define _CIRCUIT_PURPOSE_MAX 11
#define RELAY_COMMAND_BEGIN 1
@@ -228,6 +231,9 @@
#define RELAY_COMMAND_INTRODUCE2 35
#define RELAY_COMMAND_RENDEZVOUS1 36
#define RELAY_COMMAND_RENDEZVOUS2 37
+/* DOCDOC Spec these next two. */
+#define RELAY_COMMAND_INTRO_ESTABLISHED 38
+#define RELAY_COMMAND_RENDEZVOUS_ESTABLISHED 39
#define _MIN_END_STREAM_REASON 1
#define END_STREAM_REASON_MISC 1
@@ -1062,6 +1068,7 @@ int rend_service_init_keys(void);
int rend_services_init(void);
void rend_service_intro_is_ready(circuit_t *circuit);
+int rend_service_intro_established(circuit_t *circuit, const char *request, int request_len);
void rend_service_rendezvous_is_ready(circuit_t *circuit);
int rend_service_introduce(circuit_t *circuit, const char *request, int request_len);
diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c
index f75a8182b7..878e83e3bd 100644
--- a/src/or/rendcommon.c
+++ b/src/or/rendcommon.c
@@ -278,6 +278,13 @@ void rend_process_relay_cell(circuit_t *circ, int command, int length,
/* r = rend_client_rendezvous(circ,payload,length); */
log_fn(LOG_NOTICE, "Ignoring a rendezvous2 cell");
break;
+ case RELAY_COMMAND_INTRO_ESTABLISHED:
+ r = rend_service_intro_established(circ,payload,length);
+ break;
+ case RELAY_COMMAND_RENDEZVOUS_ESTABLISHED:
+ /* r = rend_client_rendezvous_established(circ,payload,length); */
+ log_fn(LOG_NOTICE, "Ignoring a rendezvous_established cell");
+ break;
default:
assert(0);
}
diff --git a/src/or/rendmid.c b/src/or/rendmid.c
index 691af35878..fa24aed7ea 100644
--- a/src/or/rendmid.c
+++ b/src/or/rendmid.c
@@ -75,6 +75,14 @@ rend_mid_establish_intro(circuit_t *circ, const char *request, int request_len)
circuit_mark_for_close(c);
}
+ /* Acknlowedge the request. */
+ if (connection_edge_send_command(NULL,circ,
+ RELAY_COMMAND_INTRO_ESTABLISHED,
+ "", 0, NULL)<0) {
+ log_fn(LOG_WARN, "Couldn't send INTRO_ESTABLISHED cell");
+ goto err;
+ }
+
/* Now, set up this circuit. */
circ->purpose = CIRCUIT_PURPOSE_INTRO_POINT;
memcpy(circ->rend_pk_digest, pk_digest, 20);
@@ -168,6 +176,14 @@ rend_mid_establish_rendezvous(circuit_t *circ, const char *request, int request_
goto err;
}
+ /* Acknlowedge the request. */
+ if (connection_edge_send_command(NULL,circ,
+ RELAY_COMMAND_RENDEZVOUS_ESTABLISHED,
+ "", 0, NULL)<0) {
+ log_fn(LOG_WARN, "Couldn't send RENDEZVOUS_ESTABLISHED cell");
+ goto err;
+ }
+
circ->purpose = CIRCUIT_PURPOSE_REND_POINT_WAITING;
memcpy(circ->rend_cookie, request, REND_COOKIE_LEN);
diff --git a/src/or/rendservice.c b/src/or/rendservice.c
index e05998c71b..31f0c8c5dc 100644
--- a/src/or/rendservice.c
+++ b/src/or/rendservice.c
@@ -320,7 +320,7 @@ rend_service_introduce(circuit_t *circuit, const char *request, int request_len)
log_fn(LOG_INFO, "Received INTRODUCE2 cell for service %s on circ %d",
hexid, circuit->n_circ_id);
- if (circuit->purpose != CIRCUIT_PURPOSE_S_ESTABLISH_INTRO) {
+ if (circuit->purpose != CIRCUIT_PURPOSE_S_INTRO) {
log_fn(LOG_WARN, "Got an INTRODUCE2 over a non-introduction circuit %d",
circuit->n_circ_id);
return -1;
@@ -504,6 +504,22 @@ rend_service_intro_is_ready(circuit_t *circuit)
circuit_mark_for_close(circuit);
}
+/* Handle an intro_established cell. */
+int
+rend_service_intro_established(circuit_t *circuit, const char *request, int request_len)
+{
+ if (circuit->purpose != CIRCUIT_PURPOSE_S_ESTABLISH_INTRO) {
+ log_fn(LOG_WARN, "received INTRO_ESTABLISHED cell on non-intro circuit");
+ goto err;
+ }
+ circuit->purpose = CIRCUIT_PURPOSE_S_INTRO;
+
+ return 0;
+ err:
+ circuit_mark_for_close(circuit);
+ return -1;
+}
+
/* Called once a circuit to a rendezvous point is ready: sends a
* RELAY_COMMAND_RENDEZVOUS1 cell.
*/
@@ -569,6 +585,33 @@ rend_service_rendezvous_is_ready(circuit_t *circuit)
* Manage introduction points
******/
+static circuit_t *
+find_intro_circuit(routerinfo_t *router, const char *pk_digest)
+{
+ circuit_t *circ = NULL;
+
+ while ((circ = circuit_get_next_by_pk_and_purpose(circ,pk_digest,
+ CIRCUIT_PURPOSE_S_INTRO))) {
+ assert(circ->cpath);
+ if (circ->cpath->prev->addr == router->addr &&
+ circ->cpath->prev->port == router->or_port) {
+ return circ;
+ }
+ }
+
+ circ = NULL;
+ while ((circ = circuit_get_next_by_pk_and_purpose(circ,pk_digest,
+ CIRCUIT_PURPOSE_S_ESTABLISH_INTRO))) {
+ assert(circ->cpath);
+ if (circ->cpath->prev->addr == router->addr &&
+ circ->cpath->prev->port == router->or_port) {
+ return circ;
+ }
+ }
+ return NULL;
+}
+
+
/* For every service, check how many intro points it currently has, and:
* - Pick new intro points as necessary.
* - Launch circuits to any new intro points.
@@ -579,9 +622,8 @@ int rend_services_init(void) {
routerinfo_t *router;
routerlist_t *rl;
rend_service_t *service;
- circuit_t *circ;
char *desc, *intro;
- int changed, found, prev_intro_nodes, desc_len;
+ int changed, prev_intro_nodes, desc_len;
router_get_routerlist(&rl);
@@ -593,26 +635,11 @@ int rend_services_init(void) {
/* Find out which introduction points we really have for this service. */
for (j=0;j< smartlist_len(service->intro_nodes); ++j) {
-
router = router_get_by_nickname(smartlist_get(service->intro_nodes,j));
- if (!router)
- goto remove_point;
- circ = NULL;
- found = 1;
- while ((circ = circuit_get_next_by_pk_and_purpose(
- circ,service->pk_digest,
- CIRCUIT_PURPOSE_S_ESTABLISH_INTRO))) {
- assert(circ->cpath);
- if (circ->cpath->prev->addr == router->addr &&
- circ->cpath->prev->port == router->or_port) {
- found = 1; break;
- }
+ if (!router || !find_intro_circuit(router,service->pk_digest)) {
+ smartlist_del(service->intro_nodes,j--);
+ changed = 1;
}
- if (found) continue;
-
- remove_point:
- smartlist_del(service->intro_nodes,j--);
- changed = 1;
}
/* We have enough intro points, and the intro points we thought we had were