Loading ChangeLog +2 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,8 @@ Changes in version 0.2.0.8-alpha - 2007-10-12 - Use annotations to record the purpose of each descriptor. - Disable the SETROUTERPURPOSE controller command: it is now obsolete. - Controllers should now specify cache=no or cache=yes when using the +POSTDESCRIPTOR command. - Bridge authorities now write bridge descriptors to disk, meaning we can export them to other programs and begin distributing them to blocked users. Loading doc/spec/control-spec.txt +7 −1 Original line number Diff line number Diff line Loading @@ -635,12 +635,18 @@ $Id$ 3.14. POSTDESCRIPTOR Sent from the client to the server. The syntax is: "+POSTDESCRIPTOR" [SP "purpose=" Purpose] CRLF Descriptor CRLF "." CRLF "+POSTDESCRIPTOR" [SP "purpose=" Purpose] [SP "cache=" Cache] CRLF Descriptor CRLF "." CRLF This message informs the server about a new descriptor. If Purpose is specified, it must be either "general" or "controller", else we return a 552 error. If Cache is specified, it must be either "no" or "yes", else we return a 552 error. If Cache is not specified, Tor will decide for itself whether it wants to cache the descriptor, and controllers must not rely on its choice. The descriptor, when parsed, must contain a number of well-specified fields, including fields for its nickname and identity. Loading src/or/control.c +47 −41 Original line number Diff line number Diff line Loading @@ -1878,35 +1878,19 @@ handle_control_getinfo(control_connection_t *conn, uint32_t len, return 0; } /** If *<b>string</b> contains a recognized purpose (for * circuits if <b>for_circuits</b> is 1, else for routers), * possibly prefaced with the string "purpose=", then assign it * and return 0. Otherwise return -1. * * If it's prefaced with "purpose=", then set *<b>string</b> to * the remainder of the string. */ static int get_purpose(char **string, int for_circuits, uint8_t *purpose) /** Given a string, convert it to a circuit purpose. */ static uint8_t circuit_purpose_from_string(const char *string) { if (!strcmpstart(*string, "purpose=")) *string += strlen("purpose="); if (!strcmpstart(string, "purpose=")) string += strlen("purpose="); if (!for_circuits) { int r = router_purpose_from_string(*string); if (r == ROUTER_PURPOSE_UNKNOWN) return -1; *purpose = r; return 0; } if (!strcmp(*string, "general")) *purpose = CIRCUIT_PURPOSE_C_GENERAL; else if (!strcmp(*string, "controller")) *purpose = CIRCUIT_PURPOSE_CONTROLLER; else { /* not a recognized purpose */ return -1; } return 0; if (!strcmp(string, "general")) return CIRCUIT_PURPOSE_C_GENERAL; else if (!strcmp(string, "controller")) return CIRCUIT_PURPOSE_CONTROLLER; else return CIRCUIT_PURPOSE_UNKNOWN; } /** Return a newly allocated smartlist containing the arguments to the command Loading Loading @@ -1963,7 +1947,8 @@ handle_control_extendcircuit(control_connection_t *conn, uint32_t len, if (zero_circ && smartlist_len(args)>2) { char *purp = smartlist_get(args,2); if (get_purpose(&purp, 1, &intended_purpose) < 0) { intended_purpose = circuit_purpose_from_string(purp); if (intended_purpose == CIRCUIT_PURPOSE_UNKNOWN) { connection_printf_to_buf(conn, "552 Unknown purpose \"%s\"\r\n", purp); SMARTLIST_FOREACH(args, char *, cp, tor_free(cp)); smartlist_free(args); Loading Loading @@ -2061,7 +2046,8 @@ handle_control_setcircuitpurpose(control_connection_t *conn, { char *purp = smartlist_get(args,1); if (get_purpose(&purp, 1, &new_purpose) < 0) { new_purpose = circuit_purpose_from_string(purp); if (new_purpose == CIRCUIT_PURPOSE_UNKNOWN) { connection_printf_to_buf(conn, "552 Unknown purpose \"%s\"\r\n", purp); goto done; } Loading Loading @@ -2178,6 +2164,7 @@ handle_control_postdescriptor(control_connection_t *conn, uint32_t len, char *desc; const char *msg=NULL; uint8_t purpose = ROUTER_PURPOSE_GENERAL; int cache = 0; /* eventually, we may switch this to 1 */ char *cp = memchr(body, '\n', len); smartlist_t *args = smartlist_create(); Loading @@ -2186,21 +2173,37 @@ handle_control_postdescriptor(control_connection_t *conn, uint32_t len, smartlist_split_string(args, body, " ", SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0); if (smartlist_len(args)) { char *purp = smartlist_get(args,0); if (get_purpose(&purp, 0, &purpose) < 0) { SMARTLIST_FOREACH(args, char *, option, { if (!strcasecmpstart(option, "purpose=")) { option += strlen("purpose="); purpose = router_purpose_from_string(option); if (purpose == ROUTER_PURPOSE_UNKNOWN) { connection_printf_to_buf(conn, "552 Unknown purpose \"%s\"\r\n", purp); SMARTLIST_FOREACH(args, char *, arg, tor_free(arg)); smartlist_free(args); return 0; option); goto done; } } else if (!strcasecmpstart(option, "cache=")) { option += strlen("cache="); if (!strcmp(option, "no")) cache = 0; else if (!strcmp(option, "yes")) cache = 1; else { connection_printf_to_buf(conn, "552 Unknown cache request \"%s\"\r\n", option); goto done; } SMARTLIST_FOREACH(args, char *, arg, tor_free(arg)); smartlist_free(args); } else { /* unrecognized argument? */ connection_printf_to_buf(conn, "512 Unexpected argument \"%s\" to postdescriptor\r\n", option); goto done; } }); read_escaped_data(cp, len-(cp-body), &desc); switch (router_load_single_router(desc, purpose, &msg)) { switch (router_load_single_router(desc, purpose, cache, &msg)) { case -1: if (!msg) msg = "Could not parse descriptor"; connection_printf_to_buf(conn, "554 %s\r\n", msg); Loading @@ -2215,6 +2218,9 @@ handle_control_postdescriptor(control_connection_t *conn, uint32_t len, } tor_free(desc); done: SMARTLIST_FOREACH(args, char *, arg, tor_free(arg)); smartlist_free(args); return 0; } Loading src/or/or.h +4 −1 Original line number Diff line number Diff line Loading @@ -451,6 +451,9 @@ typedef enum { /** A controller made this circuit and Tor should not use it. */ #define CIRCUIT_PURPOSE_CONTROLLER 18 #define _CIRCUIT_PURPOSE_MAX 18 /** A catch-all for unrecognized purposes. Currently we don't expect * to make or see any circuits with this purpose. */ #define CIRCUIT_PURPOSE_UNKNOWN 255 /** True iff the circuit purpose <b>p</b> is for a circuit that * originated at this node. */ Loading Loading @@ -3600,7 +3603,7 @@ int router_add_to_routerlist(routerinfo_t *router, const char **msg, void router_add_extrainfo_to_routerlist(extrainfo_t *ei, const char **msg, int from_cache, int from_fetch); void routerlist_remove_old_routers(void); int router_load_single_router(const char *s, uint8_t purpose, int router_load_single_router(const char *s, uint8_t purpose, int cache, const char **msg); void router_load_routers_from_string(const char *s, const char *eos, saved_location_t saved_location, Loading src/or/routerlist.c +5 −1 Original line number Diff line number Diff line Loading @@ -2991,7 +2991,8 @@ routerlist_descriptors_added(smartlist_t *sl) * This is used only by the controller. */ int router_load_single_router(const char *s, uint8_t purpose, const char **msg) router_load_single_router(const char *s, uint8_t purpose, int cache, const char **msg) { routerinfo_t *ri; int r; Loading @@ -3017,6 +3018,9 @@ router_load_single_router(const char *s, uint8_t purpose, const char **msg) return 0; } if (!cache) /* obey the preference of the controller */ ri->cache_info.do_not_cache = 1; lst = smartlist_create(); smartlist_add(lst, ri); routers_update_status_from_networkstatus(lst, 0); Loading src/or/router.c +1 −1 File changed.Contains only whitespace changes. Show changes Loading
ChangeLog +2 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,8 @@ Changes in version 0.2.0.8-alpha - 2007-10-12 - Use annotations to record the purpose of each descriptor. - Disable the SETROUTERPURPOSE controller command: it is now obsolete. - Controllers should now specify cache=no or cache=yes when using the +POSTDESCRIPTOR command. - Bridge authorities now write bridge descriptors to disk, meaning we can export them to other programs and begin distributing them to blocked users. Loading
doc/spec/control-spec.txt +7 −1 Original line number Diff line number Diff line Loading @@ -635,12 +635,18 @@ $Id$ 3.14. POSTDESCRIPTOR Sent from the client to the server. The syntax is: "+POSTDESCRIPTOR" [SP "purpose=" Purpose] CRLF Descriptor CRLF "." CRLF "+POSTDESCRIPTOR" [SP "purpose=" Purpose] [SP "cache=" Cache] CRLF Descriptor CRLF "." CRLF This message informs the server about a new descriptor. If Purpose is specified, it must be either "general" or "controller", else we return a 552 error. If Cache is specified, it must be either "no" or "yes", else we return a 552 error. If Cache is not specified, Tor will decide for itself whether it wants to cache the descriptor, and controllers must not rely on its choice. The descriptor, when parsed, must contain a number of well-specified fields, including fields for its nickname and identity. Loading
src/or/control.c +47 −41 Original line number Diff line number Diff line Loading @@ -1878,35 +1878,19 @@ handle_control_getinfo(control_connection_t *conn, uint32_t len, return 0; } /** If *<b>string</b> contains a recognized purpose (for * circuits if <b>for_circuits</b> is 1, else for routers), * possibly prefaced with the string "purpose=", then assign it * and return 0. Otherwise return -1. * * If it's prefaced with "purpose=", then set *<b>string</b> to * the remainder of the string. */ static int get_purpose(char **string, int for_circuits, uint8_t *purpose) /** Given a string, convert it to a circuit purpose. */ static uint8_t circuit_purpose_from_string(const char *string) { if (!strcmpstart(*string, "purpose=")) *string += strlen("purpose="); if (!strcmpstart(string, "purpose=")) string += strlen("purpose="); if (!for_circuits) { int r = router_purpose_from_string(*string); if (r == ROUTER_PURPOSE_UNKNOWN) return -1; *purpose = r; return 0; } if (!strcmp(*string, "general")) *purpose = CIRCUIT_PURPOSE_C_GENERAL; else if (!strcmp(*string, "controller")) *purpose = CIRCUIT_PURPOSE_CONTROLLER; else { /* not a recognized purpose */ return -1; } return 0; if (!strcmp(string, "general")) return CIRCUIT_PURPOSE_C_GENERAL; else if (!strcmp(string, "controller")) return CIRCUIT_PURPOSE_CONTROLLER; else return CIRCUIT_PURPOSE_UNKNOWN; } /** Return a newly allocated smartlist containing the arguments to the command Loading Loading @@ -1963,7 +1947,8 @@ handle_control_extendcircuit(control_connection_t *conn, uint32_t len, if (zero_circ && smartlist_len(args)>2) { char *purp = smartlist_get(args,2); if (get_purpose(&purp, 1, &intended_purpose) < 0) { intended_purpose = circuit_purpose_from_string(purp); if (intended_purpose == CIRCUIT_PURPOSE_UNKNOWN) { connection_printf_to_buf(conn, "552 Unknown purpose \"%s\"\r\n", purp); SMARTLIST_FOREACH(args, char *, cp, tor_free(cp)); smartlist_free(args); Loading Loading @@ -2061,7 +2046,8 @@ handle_control_setcircuitpurpose(control_connection_t *conn, { char *purp = smartlist_get(args,1); if (get_purpose(&purp, 1, &new_purpose) < 0) { new_purpose = circuit_purpose_from_string(purp); if (new_purpose == CIRCUIT_PURPOSE_UNKNOWN) { connection_printf_to_buf(conn, "552 Unknown purpose \"%s\"\r\n", purp); goto done; } Loading Loading @@ -2178,6 +2164,7 @@ handle_control_postdescriptor(control_connection_t *conn, uint32_t len, char *desc; const char *msg=NULL; uint8_t purpose = ROUTER_PURPOSE_GENERAL; int cache = 0; /* eventually, we may switch this to 1 */ char *cp = memchr(body, '\n', len); smartlist_t *args = smartlist_create(); Loading @@ -2186,21 +2173,37 @@ handle_control_postdescriptor(control_connection_t *conn, uint32_t len, smartlist_split_string(args, body, " ", SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0); if (smartlist_len(args)) { char *purp = smartlist_get(args,0); if (get_purpose(&purp, 0, &purpose) < 0) { SMARTLIST_FOREACH(args, char *, option, { if (!strcasecmpstart(option, "purpose=")) { option += strlen("purpose="); purpose = router_purpose_from_string(option); if (purpose == ROUTER_PURPOSE_UNKNOWN) { connection_printf_to_buf(conn, "552 Unknown purpose \"%s\"\r\n", purp); SMARTLIST_FOREACH(args, char *, arg, tor_free(arg)); smartlist_free(args); return 0; option); goto done; } } else if (!strcasecmpstart(option, "cache=")) { option += strlen("cache="); if (!strcmp(option, "no")) cache = 0; else if (!strcmp(option, "yes")) cache = 1; else { connection_printf_to_buf(conn, "552 Unknown cache request \"%s\"\r\n", option); goto done; } SMARTLIST_FOREACH(args, char *, arg, tor_free(arg)); smartlist_free(args); } else { /* unrecognized argument? */ connection_printf_to_buf(conn, "512 Unexpected argument \"%s\" to postdescriptor\r\n", option); goto done; } }); read_escaped_data(cp, len-(cp-body), &desc); switch (router_load_single_router(desc, purpose, &msg)) { switch (router_load_single_router(desc, purpose, cache, &msg)) { case -1: if (!msg) msg = "Could not parse descriptor"; connection_printf_to_buf(conn, "554 %s\r\n", msg); Loading @@ -2215,6 +2218,9 @@ handle_control_postdescriptor(control_connection_t *conn, uint32_t len, } tor_free(desc); done: SMARTLIST_FOREACH(args, char *, arg, tor_free(arg)); smartlist_free(args); return 0; } Loading
src/or/or.h +4 −1 Original line number Diff line number Diff line Loading @@ -451,6 +451,9 @@ typedef enum { /** A controller made this circuit and Tor should not use it. */ #define CIRCUIT_PURPOSE_CONTROLLER 18 #define _CIRCUIT_PURPOSE_MAX 18 /** A catch-all for unrecognized purposes. Currently we don't expect * to make or see any circuits with this purpose. */ #define CIRCUIT_PURPOSE_UNKNOWN 255 /** True iff the circuit purpose <b>p</b> is for a circuit that * originated at this node. */ Loading Loading @@ -3600,7 +3603,7 @@ int router_add_to_routerlist(routerinfo_t *router, const char **msg, void router_add_extrainfo_to_routerlist(extrainfo_t *ei, const char **msg, int from_cache, int from_fetch); void routerlist_remove_old_routers(void); int router_load_single_router(const char *s, uint8_t purpose, int router_load_single_router(const char *s, uint8_t purpose, int cache, const char **msg); void router_load_routers_from_string(const char *s, const char *eos, saved_location_t saved_location, Loading
src/or/routerlist.c +5 −1 Original line number Diff line number Diff line Loading @@ -2991,7 +2991,8 @@ routerlist_descriptors_added(smartlist_t *sl) * This is used only by the controller. */ int router_load_single_router(const char *s, uint8_t purpose, const char **msg) router_load_single_router(const char *s, uint8_t purpose, int cache, const char **msg) { routerinfo_t *ri; int r; Loading @@ -3017,6 +3018,9 @@ router_load_single_router(const char *s, uint8_t purpose, const char **msg) return 0; } if (!cache) /* obey the preference of the controller */ ri->cache_info.do_not_cache = 1; lst = smartlist_create(); smartlist_add(lst, ri); routers_update_status_from_networkstatus(lst, 0); Loading