mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-30 23:53:32 +01:00
Unindent long-misindented blocks.
We switched these to be "if (1) " a while back, so we could keep the indentation and avoid merge conflicts. But it's nice to clean up from time to time.
This commit is contained in:
parent
26651d7fdb
commit
97ed2ce085
224
src/or/channel.c
224
src/or/channel.c
@ -2318,122 +2318,120 @@ channel_flush_some_cells_from_outgoing_queue(channel_t *chan,
|
|||||||
free_q = 0;
|
free_q = 0;
|
||||||
handed_off = 0;
|
handed_off = 0;
|
||||||
|
|
||||||
if (1) {
|
/* Figure out how big it is for statistical purposes */
|
||||||
/* Figure out how big it is for statistical purposes */
|
cell_size = channel_get_cell_queue_entry_size(chan, q);
|
||||||
cell_size = channel_get_cell_queue_entry_size(chan, q);
|
/*
|
||||||
/*
|
* Okay, we have a good queue entry, try to give it to the lower
|
||||||
* Okay, we have a good queue entry, try to give it to the lower
|
* layer.
|
||||||
* layer.
|
*/
|
||||||
*/
|
switch (q->type) {
|
||||||
switch (q->type) {
|
case CELL_QUEUE_FIXED:
|
||||||
case CELL_QUEUE_FIXED:
|
if (q->u.fixed.cell) {
|
||||||
if (q->u.fixed.cell) {
|
if (chan->write_cell(chan,
|
||||||
if (chan->write_cell(chan,
|
q->u.fixed.cell)) {
|
||||||
q->u.fixed.cell)) {
|
++flushed;
|
||||||
++flushed;
|
channel_timestamp_xmit(chan);
|
||||||
channel_timestamp_xmit(chan);
|
++(chan->n_cells_xmitted);
|
||||||
++(chan->n_cells_xmitted);
|
chan->n_bytes_xmitted += cell_size;
|
||||||
chan->n_bytes_xmitted += cell_size;
|
|
||||||
free_q = 1;
|
|
||||||
handed_off = 1;
|
|
||||||
}
|
|
||||||
/* Else couldn't write it; leave it on the queue */
|
|
||||||
} else {
|
|
||||||
/* This shouldn't happen */
|
|
||||||
log_info(LD_CHANNEL,
|
|
||||||
"Saw broken cell queue entry of type CELL_QUEUE_FIXED "
|
|
||||||
"with no cell on channel %p "
|
|
||||||
"(global ID " U64_FORMAT ").",
|
|
||||||
chan, U64_PRINTF_ARG(chan->global_identifier));
|
|
||||||
/* Throw it away */
|
|
||||||
free_q = 1;
|
|
||||||
handed_off = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CELL_QUEUE_PACKED:
|
|
||||||
if (q->u.packed.packed_cell) {
|
|
||||||
if (chan->write_packed_cell(chan,
|
|
||||||
q->u.packed.packed_cell)) {
|
|
||||||
++flushed;
|
|
||||||
channel_timestamp_xmit(chan);
|
|
||||||
++(chan->n_cells_xmitted);
|
|
||||||
chan->n_bytes_xmitted += cell_size;
|
|
||||||
free_q = 1;
|
|
||||||
handed_off = 1;
|
|
||||||
}
|
|
||||||
/* Else couldn't write it; leave it on the queue */
|
|
||||||
} else {
|
|
||||||
/* This shouldn't happen */
|
|
||||||
log_info(LD_CHANNEL,
|
|
||||||
"Saw broken cell queue entry of type CELL_QUEUE_PACKED "
|
|
||||||
"with no cell on channel %p "
|
|
||||||
"(global ID " U64_FORMAT ").",
|
|
||||||
chan, U64_PRINTF_ARG(chan->global_identifier));
|
|
||||||
/* Throw it away */
|
|
||||||
free_q = 1;
|
|
||||||
handed_off = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CELL_QUEUE_VAR:
|
|
||||||
if (q->u.var.var_cell) {
|
|
||||||
if (chan->write_var_cell(chan,
|
|
||||||
q->u.var.var_cell)) {
|
|
||||||
++flushed;
|
|
||||||
channel_timestamp_xmit(chan);
|
|
||||||
++(chan->n_cells_xmitted);
|
|
||||||
chan->n_bytes_xmitted += cell_size;
|
|
||||||
free_q = 1;
|
|
||||||
handed_off = 1;
|
|
||||||
}
|
|
||||||
/* Else couldn't write it; leave it on the queue */
|
|
||||||
} else {
|
|
||||||
/* This shouldn't happen */
|
|
||||||
log_info(LD_CHANNEL,
|
|
||||||
"Saw broken cell queue entry of type CELL_QUEUE_VAR "
|
|
||||||
"with no cell on channel %p "
|
|
||||||
"(global ID " U64_FORMAT ").",
|
|
||||||
chan, U64_PRINTF_ARG(chan->global_identifier));
|
|
||||||
/* Throw it away */
|
|
||||||
free_q = 1;
|
|
||||||
handed_off = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* Unknown type, log and free it */
|
|
||||||
log_info(LD_CHANNEL,
|
|
||||||
"Saw an unknown cell queue entry type %d on channel %p "
|
|
||||||
"(global ID " U64_FORMAT "; ignoring it."
|
|
||||||
" Someone should fix this.",
|
|
||||||
q->type, chan, U64_PRINTF_ARG(chan->global_identifier));
|
|
||||||
free_q = 1;
|
free_q = 1;
|
||||||
handed_off = 0;
|
handed_off = 1;
|
||||||
}
|
}
|
||||||
|
/* Else couldn't write it; leave it on the queue */
|
||||||
/*
|
|
||||||
* if free_q is set, we used it and should remove the queue entry;
|
|
||||||
* we have to do the free down here so TOR_SIMPLEQ_REMOVE_HEAD isn't
|
|
||||||
* accessing freed memory
|
|
||||||
*/
|
|
||||||
if (free_q) {
|
|
||||||
TOR_SIMPLEQ_REMOVE_HEAD(&chan->outgoing_queue, next);
|
|
||||||
/*
|
|
||||||
* ...and we handed a cell off to the lower layer, so we should
|
|
||||||
* update the counters.
|
|
||||||
*/
|
|
||||||
++n_channel_cells_passed_to_lower_layer;
|
|
||||||
--n_channel_cells_in_queues;
|
|
||||||
n_channel_bytes_passed_to_lower_layer += cell_size;
|
|
||||||
n_channel_bytes_in_queues -= cell_size;
|
|
||||||
channel_assert_counter_consistency();
|
|
||||||
/* Update the channel's queue size too */
|
|
||||||
chan->bytes_in_queue -= cell_size;
|
|
||||||
/* Finally, free q */
|
|
||||||
cell_queue_entry_free(q, handed_off);
|
|
||||||
q = NULL;
|
|
||||||
} else {
|
} else {
|
||||||
/* No cell removed from list, so we can't go on any further */
|
/* This shouldn't happen */
|
||||||
break;
|
log_info(LD_CHANNEL,
|
||||||
|
"Saw broken cell queue entry of type CELL_QUEUE_FIXED "
|
||||||
|
"with no cell on channel %p "
|
||||||
|
"(global ID " U64_FORMAT ").",
|
||||||
|
chan, U64_PRINTF_ARG(chan->global_identifier));
|
||||||
|
/* Throw it away */
|
||||||
|
free_q = 1;
|
||||||
|
handed_off = 0;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case CELL_QUEUE_PACKED:
|
||||||
|
if (q->u.packed.packed_cell) {
|
||||||
|
if (chan->write_packed_cell(chan,
|
||||||
|
q->u.packed.packed_cell)) {
|
||||||
|
++flushed;
|
||||||
|
channel_timestamp_xmit(chan);
|
||||||
|
++(chan->n_cells_xmitted);
|
||||||
|
chan->n_bytes_xmitted += cell_size;
|
||||||
|
free_q = 1;
|
||||||
|
handed_off = 1;
|
||||||
|
}
|
||||||
|
/* Else couldn't write it; leave it on the queue */
|
||||||
|
} else {
|
||||||
|
/* This shouldn't happen */
|
||||||
|
log_info(LD_CHANNEL,
|
||||||
|
"Saw broken cell queue entry of type CELL_QUEUE_PACKED "
|
||||||
|
"with no cell on channel %p "
|
||||||
|
"(global ID " U64_FORMAT ").",
|
||||||
|
chan, U64_PRINTF_ARG(chan->global_identifier));
|
||||||
|
/* Throw it away */
|
||||||
|
free_q = 1;
|
||||||
|
handed_off = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CELL_QUEUE_VAR:
|
||||||
|
if (q->u.var.var_cell) {
|
||||||
|
if (chan->write_var_cell(chan,
|
||||||
|
q->u.var.var_cell)) {
|
||||||
|
++flushed;
|
||||||
|
channel_timestamp_xmit(chan);
|
||||||
|
++(chan->n_cells_xmitted);
|
||||||
|
chan->n_bytes_xmitted += cell_size;
|
||||||
|
free_q = 1;
|
||||||
|
handed_off = 1;
|
||||||
|
}
|
||||||
|
/* Else couldn't write it; leave it on the queue */
|
||||||
|
} else {
|
||||||
|
/* This shouldn't happen */
|
||||||
|
log_info(LD_CHANNEL,
|
||||||
|
"Saw broken cell queue entry of type CELL_QUEUE_VAR "
|
||||||
|
"with no cell on channel %p "
|
||||||
|
"(global ID " U64_FORMAT ").",
|
||||||
|
chan, U64_PRINTF_ARG(chan->global_identifier));
|
||||||
|
/* Throw it away */
|
||||||
|
free_q = 1;
|
||||||
|
handed_off = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Unknown type, log and free it */
|
||||||
|
log_info(LD_CHANNEL,
|
||||||
|
"Saw an unknown cell queue entry type %d on channel %p "
|
||||||
|
"(global ID " U64_FORMAT "; ignoring it."
|
||||||
|
" Someone should fix this.",
|
||||||
|
q->type, chan, U64_PRINTF_ARG(chan->global_identifier));
|
||||||
|
free_q = 1;
|
||||||
|
handed_off = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* if free_q is set, we used it and should remove the queue entry;
|
||||||
|
* we have to do the free down here so TOR_SIMPLEQ_REMOVE_HEAD isn't
|
||||||
|
* accessing freed memory
|
||||||
|
*/
|
||||||
|
if (free_q) {
|
||||||
|
TOR_SIMPLEQ_REMOVE_HEAD(&chan->outgoing_queue, next);
|
||||||
|
/*
|
||||||
|
* ...and we handed a cell off to the lower layer, so we should
|
||||||
|
* update the counters.
|
||||||
|
*/
|
||||||
|
++n_channel_cells_passed_to_lower_layer;
|
||||||
|
--n_channel_cells_in_queues;
|
||||||
|
n_channel_bytes_passed_to_lower_layer += cell_size;
|
||||||
|
n_channel_bytes_in_queues -= cell_size;
|
||||||
|
channel_assert_counter_consistency();
|
||||||
|
/* Update the channel's queue size too */
|
||||||
|
chan->bytes_in_queue -= cell_size;
|
||||||
|
/* Finally, free q */
|
||||||
|
cell_queue_entry_free(q, handed_off);
|
||||||
|
q = NULL;
|
||||||
|
} else {
|
||||||
|
/* No cell removed from list, so we can't go on any further */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5313,35 +5313,35 @@ addressmap_register_auto(const char *from, const char *to,
|
|||||||
int from_wildcard = 0, to_wildcard = 0;
|
int from_wildcard = 0, to_wildcard = 0;
|
||||||
|
|
||||||
*msg = "whoops, forgot the error message";
|
*msg = "whoops, forgot the error message";
|
||||||
if (1) {
|
|
||||||
if (!strcmp(to, "*") || !strcmp(from, "*")) {
|
|
||||||
*msg = "can't remap from or to *";
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
/* Detect asterisks in expressions of type: '*.example.com' */
|
|
||||||
if (!strncmp(from,"*.",2)) {
|
|
||||||
from += 2;
|
|
||||||
from_wildcard = 1;
|
|
||||||
}
|
|
||||||
if (!strncmp(to,"*.",2)) {
|
|
||||||
to += 2;
|
|
||||||
to_wildcard = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (to_wildcard && !from_wildcard) {
|
if (!strcmp(to, "*") || !strcmp(from, "*")) {
|
||||||
*msg = "can only use wildcard (i.e. '*.') if 'from' address "
|
*msg = "can't remap from or to *";
|
||||||
"uses wildcard also";
|
return -1;
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (address_is_invalid_destination(to, 1)) {
|
|
||||||
*msg = "destination is invalid";
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
addressmap_register(from, tor_strdup(to), expires, addrmap_source,
|
|
||||||
from_wildcard, to_wildcard);
|
|
||||||
}
|
}
|
||||||
|
/* Detect asterisks in expressions of type: '*.example.com' */
|
||||||
|
if (!strncmp(from,"*.",2)) {
|
||||||
|
from += 2;
|
||||||
|
from_wildcard = 1;
|
||||||
|
}
|
||||||
|
if (!strncmp(to,"*.",2)) {
|
||||||
|
to += 2;
|
||||||
|
to_wildcard = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (to_wildcard && !from_wildcard) {
|
||||||
|
*msg = "can only use wildcard (i.e. '*.') if 'from' address "
|
||||||
|
"uses wildcard also";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (address_is_invalid_destination(to, 1)) {
|
||||||
|
*msg = "destination is invalid";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
addressmap_register(from, tor_strdup(to), expires, addrmap_source,
|
||||||
|
from_wildcard, to_wildcard);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1857,15 +1857,15 @@ body_is_plausible(const char *body, size_t len, int purpose)
|
|||||||
if (purpose == DIR_PURPOSE_FETCH_MICRODESC) {
|
if (purpose == DIR_PURPOSE_FETCH_MICRODESC) {
|
||||||
return (!strcmpstart(body,"onion-key"));
|
return (!strcmpstart(body,"onion-key"));
|
||||||
}
|
}
|
||||||
if (1) {
|
|
||||||
if (!strcmpstart(body,"router") ||
|
if (!strcmpstart(body,"router") ||
|
||||||
!strcmpstart(body,"network-status"))
|
!strcmpstart(body,"network-status"))
|
||||||
return 1;
|
return 1;
|
||||||
for (i=0;i<32;++i) {
|
for (i=0;i<32;++i) {
|
||||||
if (!TOR_ISPRINT(body[i]) && !TOR_ISSPACE(body[i]))
|
if (!TOR_ISPRINT(body[i]) && !TOR_ISSPACE(body[i]))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3030,64 +3030,62 @@ handle_get_current_consensus(dir_connection_t *conn,
|
|||||||
smartlist_t *dir_fps = smartlist_new();
|
smartlist_t *dir_fps = smartlist_new();
|
||||||
long lifetime = NETWORKSTATUS_CACHE_LIFETIME;
|
long lifetime = NETWORKSTATUS_CACHE_LIFETIME;
|
||||||
|
|
||||||
if (1) {
|
networkstatus_t *v;
|
||||||
networkstatus_t *v;
|
time_t now = time(NULL);
|
||||||
time_t now = time(NULL);
|
const char *want_fps = NULL;
|
||||||
const char *want_fps = NULL;
|
char *flavor = NULL;
|
||||||
char *flavor = NULL;
|
int flav = FLAV_NS;
|
||||||
int flav = FLAV_NS;
|
#define CONSENSUS_URL_PREFIX "/tor/status-vote/current/consensus/"
|
||||||
#define CONSENSUS_URL_PREFIX "/tor/status-vote/current/consensus/"
|
#define CONSENSUS_FLAVORED_PREFIX "/tor/status-vote/current/consensus-"
|
||||||
#define CONSENSUS_FLAVORED_PREFIX "/tor/status-vote/current/consensus-"
|
/* figure out the flavor if any, and who we wanted to sign the thing */
|
||||||
/* figure out the flavor if any, and who we wanted to sign the thing */
|
if (!strcmpstart(url, CONSENSUS_FLAVORED_PREFIX)) {
|
||||||
if (!strcmpstart(url, CONSENSUS_FLAVORED_PREFIX)) {
|
const char *f, *cp;
|
||||||
const char *f, *cp;
|
f = url + strlen(CONSENSUS_FLAVORED_PREFIX);
|
||||||
f = url + strlen(CONSENSUS_FLAVORED_PREFIX);
|
cp = strchr(f, '/');
|
||||||
cp = strchr(f, '/');
|
if (cp) {
|
||||||
if (cp) {
|
want_fps = cp+1;
|
||||||
want_fps = cp+1;
|
flavor = tor_strndup(f, cp-f);
|
||||||
flavor = tor_strndup(f, cp-f);
|
|
||||||
} else {
|
|
||||||
flavor = tor_strdup(f);
|
|
||||||
}
|
|
||||||
flav = networkstatus_parse_flavor_name(flavor);
|
|
||||||
if (flav < 0)
|
|
||||||
flav = FLAV_NS;
|
|
||||||
} else {
|
} else {
|
||||||
if (!strcmpstart(url, CONSENSUS_URL_PREFIX))
|
flavor = tor_strdup(f);
|
||||||
want_fps = url+strlen(CONSENSUS_URL_PREFIX);
|
|
||||||
}
|
}
|
||||||
|
flav = networkstatus_parse_flavor_name(flavor);
|
||||||
v = networkstatus_get_latest_consensus_by_flavor(flav);
|
if (flav < 0)
|
||||||
|
flav = FLAV_NS;
|
||||||
if (v && !networkstatus_consensus_reasonably_live(v, now)) {
|
} else {
|
||||||
write_http_status_line(conn, 404, "Consensus is too old");
|
if (!strcmpstart(url, CONSENSUS_URL_PREFIX))
|
||||||
warn_consensus_is_too_old(v, flavor, now);
|
want_fps = url+strlen(CONSENSUS_URL_PREFIX);
|
||||||
smartlist_free(dir_fps);
|
|
||||||
geoip_note_ns_response(GEOIP_REJECT_NOT_FOUND);
|
|
||||||
tor_free(flavor);
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (v && want_fps &&
|
|
||||||
!client_likes_consensus(v, want_fps)) {
|
|
||||||
write_http_status_line(conn, 404, "Consensus not signed by sufficient "
|
|
||||||
"number of requested authorities");
|
|
||||||
smartlist_free(dir_fps);
|
|
||||||
geoip_note_ns_response(GEOIP_REJECT_NOT_ENOUGH_SIGS);
|
|
||||||
tor_free(flavor);
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
char *fp = tor_malloc_zero(DIGEST_LEN);
|
|
||||||
if (flavor)
|
|
||||||
strlcpy(fp, flavor, DIGEST_LEN);
|
|
||||||
tor_free(flavor);
|
|
||||||
smartlist_add(dir_fps, fp);
|
|
||||||
}
|
|
||||||
lifetime = (v && v->fresh_until > now) ? v->fresh_until - now : 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
v = networkstatus_get_latest_consensus_by_flavor(flav);
|
||||||
|
|
||||||
|
if (v && !networkstatus_consensus_reasonably_live(v, now)) {
|
||||||
|
write_http_status_line(conn, 404, "Consensus is too old");
|
||||||
|
warn_consensus_is_too_old(v, flavor, now);
|
||||||
|
smartlist_free(dir_fps);
|
||||||
|
geoip_note_ns_response(GEOIP_REJECT_NOT_FOUND);
|
||||||
|
tor_free(flavor);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v && want_fps &&
|
||||||
|
!client_likes_consensus(v, want_fps)) {
|
||||||
|
write_http_status_line(conn, 404, "Consensus not signed by sufficient "
|
||||||
|
"number of requested authorities");
|
||||||
|
smartlist_free(dir_fps);
|
||||||
|
geoip_note_ns_response(GEOIP_REJECT_NOT_ENOUGH_SIGS);
|
||||||
|
tor_free(flavor);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
char *fp = tor_malloc_zero(DIGEST_LEN);
|
||||||
|
if (flavor)
|
||||||
|
strlcpy(fp, flavor, DIGEST_LEN);
|
||||||
|
tor_free(flavor);
|
||||||
|
smartlist_add(dir_fps, fp);
|
||||||
|
}
|
||||||
|
lifetime = (v && v->fresh_until > now) ? v->fresh_until - now : 0;
|
||||||
|
|
||||||
if (!smartlist_len(dir_fps)) { /* we failed to create/cache cp */
|
if (!smartlist_len(dir_fps)) { /* we failed to create/cache cp */
|
||||||
write_http_status_line(conn, 503, "Network status object unavailable");
|
write_http_status_line(conn, 503, "Network status object unavailable");
|
||||||
smartlist_free(dir_fps);
|
smartlist_free(dir_fps);
|
||||||
@ -3122,21 +3120,19 @@ handle_get_current_consensus(dir_connection_t *conn,
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (1) {
|
tor_addr_t addr;
|
||||||
tor_addr_t addr;
|
if (tor_addr_parse(&addr, (TO_CONN(conn))->address) >= 0) {
|
||||||
if (tor_addr_parse(&addr, (TO_CONN(conn))->address) >= 0) {
|
geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS,
|
||||||
geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS,
|
&addr, NULL,
|
||||||
&addr, NULL,
|
time(NULL));
|
||||||
time(NULL));
|
geoip_note_ns_response(GEOIP_SUCCESS);
|
||||||
geoip_note_ns_response(GEOIP_SUCCESS);
|
/* Note that a request for a network status has started, so that we
|
||||||
/* Note that a request for a network status has started, so that we
|
* can measure the download time later on. */
|
||||||
* can measure the download time later on. */
|
if (conn->dirreq_id)
|
||||||
if (conn->dirreq_id)
|
geoip_start_dirreq(conn->dirreq_id, dlen, DIRREQ_TUNNELED);
|
||||||
geoip_start_dirreq(conn->dirreq_id, dlen, DIRREQ_TUNNELED);
|
else
|
||||||
else
|
geoip_start_dirreq(TO_CONN(conn)->global_identifier, dlen,
|
||||||
geoip_start_dirreq(TO_CONN(conn)->global_identifier, dlen,
|
DIRREQ_DIRECT);
|
||||||
DIRREQ_DIRECT);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
write_http_response_header(conn, -1, compressed,
|
write_http_response_header(conn, -1, compressed,
|
||||||
|
Loading…
Reference in New Issue
Block a user