mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-27 13:53:31 +01:00
Controllers should now specify cache=no or cache=yes when using
the +POSTDESCRIPTOR command. svn:r11892
This commit is contained in:
parent
ad8757fbeb
commit
3977ccbc80
@ -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.
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
@ -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);
|
||||
@ -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;
|
||||
}
|
||||
@ -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();
|
||||
@ -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) {
|
||||
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;
|
||||
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",
|
||||
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;
|
||||
}
|
||||
} else { /* unrecognized argument? */
|
||||
connection_printf_to_buf(conn,
|
||||
"512 Unexpected argument \"%s\" to postdescriptor\r\n", option);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
SMARTLIST_FOREACH(args, char *, arg, tor_free(arg));
|
||||
smartlist_free(args);
|
||||
});
|
||||
|
||||
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);
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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. */
|
||||
@ -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,
|
||||
|
@ -1803,7 +1803,7 @@ router_purpose_to_string(uint8_t p)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** Given a string, convert it to a router purpose. */
|
||||
/** Given a string, convert it to a router purpose. */
|
||||
uint8_t
|
||||
router_purpose_from_string(const char *s)
|
||||
{
|
||||
|
@ -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;
|
||||
@ -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…
Reference in New Issue
Block a user