# Replies
Reply codes follow the same 3-character format as used by SMTP, with the
first character defining a status, the second character defining a
subsystem, and the third designating fine-grained information.
The TC protocol currently uses the following first characters:
```text
2yz Positive Completion Reply
The command was successful; a new request can be started.
4yz Temporary Negative Completion reply
The command was unsuccessful but might be reattempted later.
5yz Permanent Negative Completion Reply
The command was unsuccessful; the client should not try exactly
that sequence of commands again.
6yz Asynchronous Reply
Sent out-of-order in response to an earlier SETEVENTS command.
The following second characters are used:
x0z Syntax
Sent in response to ill-formed or nonsensical commands.
x1z Protocol
Refers to operations of the Tor Control protocol.
x5z Tor
Refers to actual operations of Tor system.
The following codes are defined:
250 OK
251 Operation was unnecessary
[Tor has declined to perform the operation, but no harm was done.]
451 Resource exhausted
500 Syntax error: protocol
510 Unrecognized command
511 Unimplemented command
512 Syntax error in command argument
513 Unrecognized command argument
514 Authentication required
515 Bad authentication
550 Unspecified Tor error
551 Internal error
[Something went wrong inside Tor, so that the client's
request couldn't be fulfilled.]
552 Unrecognized entity
[A configuration key, a stream ID, circuit ID, event,
mentioned in the command did not actually exist.]
553 Invalid configuration value
[The client tried to set a configuration option to an
incorrect, ill-formed, or impossible value.]
554 Invalid descriptor
555 Unmanaged entity
650 Asynchronous event notification
```
Unless specified to have specific contents, the human-readable messages
in error replies should not be relied upon to match those in this document.
## Asynchronous events
These replies can be sent after a corresponding SETEVENTS command has been
received. They will not be interleaved with other Reply elements, but they
can appear between a command and its corresponding reply. For example,
this sequence is possible:
```text
C: SETEVENTS CIRC
S: 250 OK
C: GETCONF SOCKSPORT ORPORT
S: 650 CIRC 1000 EXTENDED moria1,moria2
S: 250-SOCKSPORT=9050
S: 250 ORPORT=0
But this sequence is disallowed:
C: SETEVENTS CIRC
S: 250 OK
C: GETCONF SOCKSPORT ORPORT
S: 250-SOCKSPORT=9050
S: 650 CIRC 1000 EXTENDED moria1,moria2
S: 250 ORPORT=0
```
Clients MUST tolerate more arguments in an asynchronous reply than
expected, and MUST tolerate more lines in an asynchronous reply than
expected. For instance, a client that expects a CIRC message like:
650 CIRC 1000 EXTENDED moria1,moria2
must tolerate:
```text
650-CIRC 1000 EXTENDED moria1,moria2 0xBEEF
650-EXTRAMAGIC=99
650 ANONYMITY=high
```
If clients receives extended events (selected by USEFEATUERE
EXTENDED_EVENTS in Tor 0.1.2.2-alpha..Tor-0.2.1.x, and always-on in
Tor 0.2.2.x and later), then each event line as specified below may be
followed by additional arguments and additional lines. Additional
lines will be of the form:
"650" ("-"/" ") KEYWORD \["=" ARGUMENTS\] CRLF
Additional arguments will be of the form
SP KEYWORD \["=" ( QuotedString / * NonSpDquote ) \]
Clients MUST tolerate events with arguments and keywords they do not
recognize, and SHOULD process those events as if any unrecognized
arguments and keywords were not present.
Clients SHOULD NOT depend on the order of keyword=value arguments,
and SHOULD NOT depend on there being no new keyword=value arguments
appearing between existing keyword=value arguments, though as of this
writing (Jun 2011) some do. Thus, extensions to this protocol should
add new keywords only after the existing keywords, until all
controllers have been fixed. At some point this "SHOULD NOT" might
become a "MUST NOT".
### Circuit status changed { #CIRC }
The syntax is:
```text
"650" SP "CIRC" SP CircuitID SP CircStatus [SP Path]
[SP "BUILD_FLAGS=" BuildFlags] [SP "PURPOSE=" Purpose]
[SP "HS_STATE=" HSState] [SP "REND_QUERY=" HSAddress]
[SP "TIME_CREATED=" TimeCreated]
[SP "REASON=" Reason [SP "REMOTE_REASON=" Reason]]
[SP "SOCKS_USERNAME=" EscapedUsername]
[SP "SOCKS_PASSWORD=" EscapedPassword]
[SP "HS_POW=" HSPoW ]
CRLF
CircStatus =
"LAUNCHED" / ; circuit ID assigned to new circuit
"BUILT" / ; all hops finished, can now accept streams
"GUARD_WAIT" / ; all hops finished, waiting to see if a
; circuit with a better guard will be usable.
"EXTENDED" / ; one more hop has been completed
"FAILED" / ; circuit closed (was not built)
"CLOSED" ; circuit closed (was built)
Path = LongName *("," LongName)
; In Tor versions 0.1.2.2-alpha through 0.2.2.1-alpha with feature
; VERBOSE_NAMES turned off and before version 0.1.2.2-alpha, Path
; is as follows:
; Path = ServerID *("," ServerID)
BuildFlags = BuildFlag *("," BuildFlag)
BuildFlag = "ONEHOP_TUNNEL" / "IS_INTERNAL" /
"NEED_CAPACITY" / "NEED_UPTIME"
Purpose = "GENERAL" / "HS_CLIENT_INTRO" / "HS_CLIENT_REND" /
"HS_SERVICE_INTRO" / "HS_SERVICE_REND" / "TESTING" /
"CONTROLLER" / "MEASURE_TIMEOUT" /
"HS_VANGUARDS" / "PATH_BIAS_TESTING" /
"CIRCUIT_PADDING"
HSState = "HSCI_CONNECTING" / "HSCI_INTRO_SENT" / "HSCI_DONE" /
"HSCR_CONNECTING" / "HSCR_ESTABLISHED_IDLE" /
"HSCR_ESTABLISHED_WAITING" / "HSCR_JOINED" /
"HSSI_CONNECTING" / "HSSI_ESTABLISHED" /
"HSSR_CONNECTING" / "HSSR_JOINED"
HSPoWType = "v1"
HSPoWEffort = 1*DIGIT
HSPoW = HSPoWType "," HSPoWEffort
EscapedUsername = QuotedString
EscapedPassword = QuotedString
HSAddress = 16*Base32Character / 56*Base32Character
Base32Character = ALPHA / "2" / "3" / "4" / "5" / "6" / "7"
TimeCreated = ISOTime2Frac
Seconds = 1*DIGIT
Microseconds = 1*DIGIT
Reason = "NONE" / "TORPROTOCOL" / "INTERNAL" / "REQUESTED" /
"HIBERNATING" / "RESOURCELIMIT" / "CONNECTFAILED" /
"OR_IDENTITY" / "OR_CONN_CLOSED" / "TIMEOUT" /
"FINISHED" / "DESTROYED" / "NOPATH" / "NOSUCHSERVICE" /
"MEASUREMENT_EXPIRED"
The path is provided only when the circuit has been extended at least one
hop.
The "BUILD_FLAGS" field is provided only in versions 0.2.3.11-alpha
and later. Clients MUST accept build flags not listed above.
Build flags are defined as follows:
ONEHOP_TUNNEL (one-hop circuit, used for tunneled directory conns)
IS_INTERNAL (internal circuit, not to be used for exiting streams)
NEED_CAPACITY (this circuit must use only high-capacity nodes)
NEED_UPTIME (this circuit must use only high-uptime nodes)
The "PURPOSE" field is provided only in versions 0.2.1.6-alpha and
later, and only if extended events are enabled (see 3.19). Clients
MUST accept purposes not listed above. Purposes are defined as
follows:
GENERAL (circuit for AP and/or directory request streams)
HS_CLIENT_INTRO (HS client-side introduction-point circuit)
HS_CLIENT_REND (HS client-side rendezvous circuit; carries AP streams)
HS_SERVICE_INTRO (HS service-side introduction-point circuit)
HS_SERVICE_REND (HS service-side rendezvous circuit)
TESTING (reachability-testing circuit; carries no traffic)
CONTROLLER (circuit built by a controller)
MEASURE_TIMEOUT (circuit being kept around to see how long it takes)
HS_VANGUARDS (circuit created ahead of time when using
HS vanguards, and later repurposed as needed)
PATH_BIAS_TESTING (circuit used to probe whether our circuits are
being deliberately closed by an attacker)
CIRCUIT_PADDING (circuit that is being held open to disguise its
true close time)
The "HS_STATE" field is provided only for hidden-service circuits,
and only in versions 0.2.3.11-alpha and later. Clients MUST accept
hidden-service circuit states not listed above. Hidden-service
circuit states are defined as follows:
HSCI_* (client-side introduction-point circuit states)
HSCI_CONNECTING (connecting to intro point)
HSCI_INTRO_SENT (sent INTRODUCE1; waiting for reply from IP)
HSCI_DONE (received reply from IP relay; closing)
HSCR_* (client-side rendezvous-point circuit states)
HSCR_CONNECTING (connecting to or waiting for reply from RP)
HSCR_ESTABLISHED_IDLE (established RP; waiting for introduction)
HSCR_ESTABLISHED_WAITING (introduction sent to HS; waiting for rend)
HSCR_JOINED (connected to HS)
HSSI_* (service-side introduction-point circuit states)
HSSI_CONNECTING (connecting to intro point)
HSSI_ESTABLISHED (established intro point)
HSSR_* (service-side rendezvous-point circuit states)
HSSR_CONNECTING (connecting to client's rend point)
HSSR_JOINED (connected to client's RP circuit)
The "SOCKS_USERNAME" and "SOCKS_PASSWORD" fields indicate the credentials
that were used by a SOCKS client to connect to Tor's SOCKS port and
initiate this circuit. (Streams for SOCKS clients connected with different
usernames and/or passwords are isolated on separate circuits if the
IsolateSOCKSAuth flag is active; see Proposal 171.) [Added in Tor
0.4.3.1-alpha.]
The "REND_QUERY" field is provided only for hidden-service-related
circuits, and only in versions 0.2.3.11-alpha and later. Clients
MUST accept hidden service addresses in formats other than that
specified above. [Added in Tor 0.4.3.1-alpha.]
The "TIME_CREATED" field is provided only in versions 0.2.3.11-alpha and
later. TIME_CREATED is the time at which the circuit was created or
cannibalized. [Added in Tor 0.4.3.1-alpha.]
The "REASON" field is provided only for FAILED and CLOSED events, and only
if extended events are enabled (see 3.19). Clients MUST accept reasons
not listed above. [Added in Tor 0.4.3.1-alpha.] Reasons are as given in
tor-spec.txt, except for:
NOPATH (Not enough nodes to make circuit)
MEASUREMENT_EXPIRED (As "TIMEOUT", except that we had left the circuit
open for measurement purposes to see how long it
would take to finish.)
IP_NOW_REDUNDANT (Closing a circuit to an introduction point that
has become redundant, since some other circuit
opened in parallel with it has succeeded.)
The "REMOTE_REASON" field is provided only when we receive a DESTROY cell or
RELAY_TRUNCATE message, and only if extended events are enabled. It contains the
actual reason given by the remote OR for closing the circuit. Clients MUST
accept reasons not listed above. Reasons are as listed in tor-spec.txt.
[Added in Tor 0.4.3.1-alpha.]
```
### Stream status changed { #STREAM }
The syntax is:
```text
"650" SP "STREAM" SP StreamID SP StreamStatus SP CircuitID SP Target
[SP "REASON=" Reason [ SP "REMOTE_REASON=" Reason ]]
[SP "SOURCE=" Source] [ SP "SOURCE_ADDR=" Address ":" Port ]
[SP "PURPOSE=" Purpose] [SP "SOCKS_USERNAME=" EscapedUsername]
[SP "SOCKS_PASSWORD=" EscapedPassword]
[SP "CLIENT_PROTOCOL=" ClientProtocol] [SP "NYM_EPOCH=" NymEpoch]
[SP "SESSION_GROUP=" SessionGroup] [SP "ISO_FIELDS=" IsoFields]
CRLF
StreamStatus =
"NEW" / ; New request to connect
"NEWRESOLVE" / ; New request to resolve an address
"REMAP" / ; Address re-mapped to another
"SENTCONNECT" / ; Sent a connect message along a circuit
"SENTRESOLVE" / ; Sent a resolve message along a circuit
"SUCCEEDED" / ; Received a reply; stream established
"FAILED" / ; Stream failed and not retriable
"CLOSED" / ; Stream closed
"DETACHED" / ; Detached from circuit; still retriable
"CONTROLLER_WAIT" ; Waiting for controller to use ATTACHSTREAM
; (new in 0.4.5.1-alpha)
"XOFF_SENT" ; XOFF has been sent for this stream
; (new in 0.4.7.5-alpha)
"XOFF_RECV" ; XOFF has been received for this stream
; (new in 0.4.7.5-alpha)
"XON_SENT" ; XON has been sent for this stream
; (new in 0.4.7.5-alpha)
"XON_RECV" ; XON has been received for this stream
; (new in 0.4.7.5-alpha)
Target = TargetAddress ":" Port
Port = an integer from 0 to 65535 inclusive
TargetAddress = Address / "(Tor_internal)"
EscapedUsername = QuotedString
EscapedPassword = QuotedString
ClientProtocol =
"SOCKS4" /
"SOCKS5" /
"TRANS" /
"NATD" /
"DNS" /
"HTTPCONNECT" /
"UNKNOWN"
NymEpoch = a nonnegative integer
SessionGroup = an integer
IsoFields = a comma-separated list of IsoField values
IsoField =
"CLIENTADDR" /
"CLIENTPORT" /
"DESTADDR" /
"DESTPORT" /
the name of a field that is valid for STREAM events
```
The circuit ID designates which circuit this stream is attached to. If
the stream is unattached, the circuit ID "0" is given. The target
indicates the address which the stream is meant to resolve or connect to;
it can be "(Tor_internal)" for a virtual stream created by the Tor program
to talk to itself.
```text
Reason = "MISC" / "RESOLVEFAILED" / "CONNECTREFUSED" /
"EXITPOLICY" / "DESTROY" / "DONE" / "TIMEOUT" /
"NOROUTE" / "HIBERNATING" / "INTERNAL"/ "RESOURCELIMIT" /
"CONNRESET" / "TORPROTOCOL" / "NOTDIRECTORY" / "END" /
"PRIVATE_ADDR"
The "REASON" field is provided only for FAILED, CLOSED, and DETACHED
events, and only if extended events are enabled (see 3.19). Clients MUST
accept reasons not listed above. Reasons are as given in tor-spec.txt,
except for:
END (We received a RELAY_END message from the other side of this
stream.)
PRIVATE_ADDR (The client tried to connect to a private address like
127.0.0.1 or 10.0.0.1 over Tor.)
[XXXX document more. -NM]
The "REMOTE_REASON" field is provided only when we receive a RELAY_END
message, and only if extended events are enabled. It contains the actual
reason given by the remote OR for closing the stream. Clients MUST accept
reasons not listed above. Reasons are as listed in tor-spec.txt.
"REMAP" events include a Source if extended events are enabled:
Source = "CACHE" / "EXIT"
Clients MUST accept sources not listed above. "CACHE" is given if
the Tor client decided to remap the address because of a cached
answer, and "EXIT" is given if the remote node we queried gave us
the new address as a response.
The "SOURCE_ADDR" field is included with NEW and NEWRESOLVE events if
extended events are enabled. It indicates the address and port
that requested the connection, and can be (e.g.) used to look up the
requesting program.
Purpose = "DIR_FETCH" / "DIR_UPLOAD" / "DNS_REQUEST" /
"USER" / "DIRPORT_TEST"
The "PURPOSE" field is provided only for NEW and NEWRESOLVE events, and
only if extended events are enabled (see 3.19). Clients MUST accept
purposes not listed above. The purposes above are defined as:
"DIR_FETCH" -- This stream is generated internally to Tor for
fetching directory information.
"DIR_UPLOAD" -- An internal stream for uploading information to
a directory authority.
"DIRPORT_TEST" -- A stream we're using to test our own directory
port to make sure it's reachable.
"DNS_REQUEST" -- A user-initiated DNS request.
"USER" -- This stream is handling user traffic, OR it's internal
to Tor, but it doesn't match one of the purposes above.
The "SOCKS_USERNAME" and "SOCKS_PASSWORD" fields indicate the credentials
that were used by a SOCKS client to connect to Tor's SOCKS port and
initiate this stream. (Streams for SOCKS clients connected with different
usernames and/or passwords are isolated on separate circuits if the
IsolateSOCKSAuth flag is active; see Proposal 171.)
The "CLIENT_PROTOCOL" field indicates the protocol that was used by a client
to initiate this stream. (Streams for clients connected with different
protocols are isolated on separate circuits if the IsolateClientProtocol
flag is active.) Controllers MUST tolerate unrecognized client protocols.
The "NYM_EPOCH" field indicates the nym epoch that was active when a client
initiated this stream. The epoch increments when the NEWNYM signal is
received. (Streams with different nym epochs are isolated on separate
circuits.)
The "SESSION_GROUP" field indicates the session group of the listener port
that a client used to initiate this stream. By default, the session group is
different for each listener port, but this can be overridden for a listener
via the "SessionGroup" option in torrc. (Streams with different session
groups are isolated on separate circuits.)
The "ISO_FIELDS" field indicates the set of STREAM event fields for which
stream isolation is enabled for the listener port that a client used to
initiate this stream. The special values "CLIENTADDR", "CLIENTPORT",
"DESTADDR", and "DESTPORT", if their correspondingly named fields are not
present, refer to the Address and Port components of the "SOURCE_ADDR" and
Target fields.
```
### OR Connection status changed { #ORCONN }
The syntax is:
```text
"650" SP "ORCONN" SP (LongName / Target) SP ORStatus [ SP "REASON="
Reason ] [ SP "NCIRCS=" NumCircuits ] [ SP "ID=" ConnID ] CRLF
ORStatus = "NEW" / "LAUNCHED" / "CONNECTED" / "FAILED" / "CLOSED"
; In Tor versions 0.1.2.2-alpha through 0.2.2.1-alpha with feature
; VERBOSE_NAMES turned off and before version 0.1.2.2-alpha, OR
; Connection is as follows:
"650" SP "ORCONN" SP (ServerID / Target) SP ORStatus [ SP "REASON="
Reason ] [ SP "NCIRCS=" NumCircuits ] CRLF
```
NEW is for incoming connections, and LAUNCHED is for outgoing
connections. CONNECTED means the TLS handshake has finished (in
either direction). FAILED means a connection is being closed that
hasn't finished its handshake, and CLOSED is for connections that
have handshaked.
A LongName or ServerID is specified unless it's a NEW connection, in
which case we don't know what server it is yet, so we use Address:Port.
If extended events are enabled (see 3.19), optional reason and
circuit counting information is provided for CLOSED and FAILED
events.
```text
Reason = "MISC" / "DONE" / "CONNECTREFUSED" /
"IDENTITY" / "CONNECTRESET" / "TIMEOUT" / "NOROUTE" /
"IOERROR" / "RESOURCELIMIT" / "PT_MISSING"
NumCircuits counts both established and pending circuits.
The ORStatus values are as follows:
NEW -- We have received a new incoming OR connection, and are starting
the server-side handshake.
LAUNCHED -- We have launched a new outgoing OR connection, and are
starting the client-side handshake.
CONNECTED -- The OR connection has been connected and the handshake is
done.
FAILED -- Our attempt to open the OR connection failed.
CLOSED -- The OR connection closed in an unremarkable way.
The Reason values for closed/failed OR connections are:
DONE -- The OR connection has shut down cleanly.
CONNECTREFUSED -- We got an ECONNREFUSED while connecting to the target
OR.
IDENTITY -- We connected to the OR, but found that its identity was
not what we expected.
CONNECTRESET -- We got an ECONNRESET or similar IO error from the
connection with the OR.
TIMEOUT -- We got an ETIMEOUT or similar IO error from the connection
with the OR, or we're closing the connection for being idle for too
long.
NOROUTE -- We got an ENOTCONN, ENETUNREACH, ENETDOWN, EHOSTUNREACH, or
similar error while connecting to the OR.
IOERROR -- We got some other IO error on our connection to the OR.
RESOURCELIMIT -- We don't have enough operating system resources (file
descriptors, buffers, etc) to connect to the OR.
PT_MISSING -- No pluggable transport was available.
MISC -- The OR connection closed for some other reason.
[First added ID parameter in 0.2.5.2-alpha]
```
### Bandwidth used in the last second { #BW }
The syntax is:
```text
"650" SP "BW" SP BytesRead SP BytesWritten *(SP Type "=" Num) CRLF
BytesRead = 1*DIGIT
BytesWritten = 1*DIGIT
Type = "DIR" / "OR" / "EXIT" / "APP" / ...
Num = 1*DIGIT
```
BytesRead and BytesWritten are the totals. \[In a future Tor version,
we may also include a breakdown of the connection types that used
bandwidth this second (not implemented yet).\]
### Log messages { #LOG }
The syntax is:
"650" SP Severity SP ReplyText CRLF
or
"650+" Severity CRLF Data 650 SP "OK" CRLF
Severity = "DEBUG" / "INFO" / "NOTICE" / "WARN"/ "ERR"
Some low-level logs may be sent from signal handlers, so their destination
logs must be signal-safe. These low-level logs include backtraces,
logging function errors, and errors in code called by logging functions.
Signal-safe logs are never sent as control port log events.
Control port message trace debug logs are never sent as control port log
events, to avoid modifying control output when debugging.
### New descriptors available { #NEWDESC }
This event is generated when new router descriptors (not microdescs or
extrainfos or anything else) are received.
Syntax:
```text
"650" SP "NEWDESC" 1*(SP LongName) CRLF
; In Tor versions 0.1.2.2-alpha through 0.2.2.1-alpha with feature
; VERBOSE_NAMES turned off and before version 0.1.2.2-alpha, it
; is as follows:
"650" SP "NEWDESC" 1*(SP ServerID) CRLF
```
### New Address mapping { #ADDRMAP }
These events are generated when a new address mapping is entered in
Tor's address map cache, or when the answer for a RESOLVE command is
found. Entries can be created by a successful or failed DNS lookup,
a successful or failed connection attempt, a RESOLVE command,
a MAPADDRESS command, the AutomapHostsOnResolve feature, or the
TrackHostExits feature.
Syntax:
```text
"650" SP "ADDRMAP" SP Address SP NewAddress SP Expiry
[SP "error=" ErrorCode] [SP "EXPIRES=" UTCExpiry] [SP "CACHED=" Cached]
[SP "STREAMID=" StreamId] CRLF
NewAddress = Address / ""
Expiry = DQUOTE ISOTime DQUOTE / "NEVER"
ErrorCode = "yes" / "internal" / "Unable to launch resolve request"
UTCExpiry = DQUOTE IsoTime DQUOTE
Cached = DQUOTE "YES" DQUOTE / DQUOTE "NO" DQUOTE
StreamId = DQUOTE StreamId DQUOTE
```
Error and UTCExpiry are only provided if extended events are enabled.
The values for Error are mostly useless. Future values will be
chosen to match 1\*(ALNUM / "\_"); the "Unable to launch resolve request"
value is a bug in Tor before 0.2.4.7-alpha.
Expiry is expressed as the local time (rather than UTC). This is a bug,
left in for backward compatibility; new code should look at UTCExpiry
instead. (If Expiry is "NEVER", UTCExpiry is omitted.)
Cached indicates whether the mapping will be stored until it expires, or if
it is just a notification in response to a RESOLVE command.
StreamId is the global stream identifier of the stream or circuit from which
the address was resolved.
### Descriptors uploaded to us in our role as authoritative dirserver { #AUTHDIR_NEWDESCS}
\[NOTE: This feature was removed in Tor 0.3.2.1-alpha.\]
Tor generates this event when it's a directory authority, and
somebody has just uploaded a server descriptor.
Syntax:
```text
"650" "+" "AUTHDIR_NEWDESCS" CRLF Action CRLF Message CRLF
Descriptor CRLF "." CRLF "650" SP "OK" CRLF
Action = "ACCEPTED" / "DROPPED" / "REJECTED"
Message = Text
```
The Descriptor field is the text of the server descriptor; the Action
field is "ACCEPTED" if we're accepting the descriptor as the new
best valid descriptor for its router, "REJECTED" if we aren't taking
the descriptor and we're complaining to the uploading relay about
it, and "DROPPED" if we decide to drop the descriptor without
complaining. The Message field is a human-readable string
explaining why we chose the Action. (It doesn't contain newlines.)
### Our descriptor changed { #DESCCHANGED }
Syntax:
"650" SP "DESCCHANGED" CRLF
\[First added in 0.1.2.2-alpha.\]
### Status events { #STATUS }
Status events (STATUS_GENERAL, STATUS_CLIENT, and STATUS_SERVER) are sent
based on occurrences in the Tor process pertaining to the general state of
the program. Generally, they correspond to log messages of severity Notice
or higher. They differ from log messages in that their format is a
specified interface.
Syntax:
```text
"650" SP StatusType SP StatusSeverity SP StatusAction
[SP StatusArguments] CRLF
StatusType = "STATUS_GENERAL" / "STATUS_CLIENT" / "STATUS_SERVER"
StatusSeverity = "NOTICE" / "WARN" / "ERR"
StatusAction = 1*ALPHA
StatusArguments = StatusArgument *(SP StatusArgument)
StatusArgument = StatusKeyword '=' StatusValue
StatusKeyword = 1*(ALNUM / "_")
StatusValue = 1*(ALNUM / '_') / QuotedString
StatusAction is a string, and StatusArguments is a series of
keyword=value pairs on the same line. Values may be space-terminated
strings, or quoted strings.
These events are always produced with EXTENDED_EVENTS and
VERBOSE_NAMES; see the explanations in the USEFEATURE section
for details.
Controllers MUST tolerate unrecognized actions, MUST tolerate
unrecognized arguments, MUST tolerate missing arguments, and MUST
tolerate arguments that arrive in any order.
Each event description below is accompanied by a recommendation for
controllers. These recommendations are suggestions only; no controller
is required to implement them.
```
Compatibility note: versions of Tor before 0.2.0.22-rc incorrectly
generated "STATUS_SERVER" as "STATUS_SEVER". To be compatible with those
versions, tools should accept both.
Actions for STATUS_GENERAL events can be as follows:
```text
CLOCK_JUMPED
"TIME=NUM"
Tor spent enough time without CPU cycles that it has closed all
its circuits and will establish them anew. This typically
happens when a laptop goes to sleep and then wakes up again. It
also happens when the system is swapping so heavily that Tor is
starving. The "time" argument specifies the number of seconds Tor
thinks it was unconscious for (or alternatively, the number of
seconds it went back in time).
This status event is sent as NOTICE severity normally, but WARN
severity if Tor is acting as a server currently.
{Recommendation for controller: ignore it, since we don't really
know what the user should do anyway. Hm.}
DANGEROUS_VERSION
"CURRENT=version"
"REASON=NEW/OBSOLETE/UNRECOMMENDED"
"RECOMMENDED=\"version, version, ...\""
Tor has found that directory servers don't recommend its version of
the Tor software. RECOMMENDED is a comma-and-space-separated string
of Tor versions that are recommended. REASON is NEW if this version
of Tor is newer than any recommended version, OBSOLETE if
this version of Tor is older than any recommended version, and
UNRECOMMENDED if some recommended versions of Tor are newer and
some are older than this version. (The "OBSOLETE" reason was called
"OLD" from Tor 0.1.2.3-alpha up to and including 0.2.0.12-alpha.)
{Controllers may want to suggest that the user upgrade OLD or
UNRECOMMENDED versions. NEW versions may be known-insecure, or may
simply be development versions.}
TOO_MANY_CONNECTIONS
"CURRENT=NUM"
Tor has reached its ulimit -n or whatever the native limit is on file
descriptors or sockets. CURRENT is the number of sockets Tor
currently has open. The user should really do something about
this. The "current" argument shows the number of connections currently
open.
{Controllers may recommend that the user increase the limit, or
increase it for them. Recommendations should be phrased in an
OS-appropriate way and automated when possible.}
BUG
"REASON=STRING"
Tor has encountered a situation that its developers never expected,
and the developers would like to learn that it happened. Perhaps
the controller can explain this to the user and encourage her to
file a bug report?
{Controllers should log bugs, but shouldn't annoy the user in case a
bug appears frequently.}
CLOCK_SKEW
SKEW="+" / "-" SECONDS
MIN_SKEW="+" / "-" SECONDS.
SOURCE="DIRSERV:" IP ":" Port /
"NETWORKSTATUS:" IP ":" Port /
"OR:" IP ":" Port /
"CONSENSUS"
If "SKEW" is present, it's an estimate of how far we are from the
time declared in the source. (In other words, if we're an hour in
the past, the value is -3600.) "MIN_SKEW" is present, it's a lower
bound. If the source is a DIRSERV, we got the current time from a
connection to a dirserver. If the source is a NETWORKSTATUS, we
decided we're skewed because we got a v2 networkstatus from far in
the future. If the source is OR, the skew comes from a NETINFO
cell from a connection to another relay. If the source is
CONSENSUS, we decided we're skewed because we got a networkstatus
consensus from the future.
{Tor should send this message to controllers when it thinks the
skew is so high that it will interfere with proper Tor operation.
Controllers shouldn't blindly adjust the clock, since the more
accurate source of skew info (DIRSERV) is currently
unauthenticated.}
BAD_LIBEVENT
"METHOD=" libevent method
"VERSION=" libevent version
"BADNESS=" "BROKEN" / "BUGGY" / "SLOW"
"RECOVERED=" "NO" / "YES"
Tor knows about bugs in using the configured event method in this
version of libevent. "BROKEN" libevents won't work at all;
"BUGGY" libevents might work okay; "SLOW" libevents will work
fine, but not quickly. If "RECOVERED" is YES, Tor managed to
switch to a more reliable (but probably slower!) libevent method.
{Controllers may want to warn the user if this event occurs, though
generally it's the fault of whoever built the Tor binary and there's
not much the user can do besides upgrade libevent or upgrade the
binary.}
DIR_ALL_UNREACHABLE
Tor believes that none of the known directory servers are
reachable -- this is most likely because the local network is
down or otherwise not working, and might help to explain for the
user why Tor appears to be broken.
{Controllers may want to warn the user if this event occurs; further
action is generally not possible.}
Actions for STATUS_CLIENT events can be as follows:
BOOTSTRAP
"PROGRESS=" num
"TAG=" Keyword
"SUMMARY=" String
["WARNING=" String]
["REASON=" Keyword]
["COUNT=" num]
["RECOMMENDATION=" Keyword]
["HOST=" QuotedString]
["HOSTADDR=" QuotedString]
Tor has made some progress at establishing a connection to the
Tor network, fetching directory information, or making its first
circuit; or it has encountered a problem while bootstrapping. This
status event is especially useful for users with slow connections
or with connectivity problems.
"Progress" gives a number between 0 and 100 for how far through
the bootstrapping process we are. "Summary" is a string that can
be displayed to the user to describe the *next* task that Tor
will tackle, i.e., the task it is working on after sending the
status event. "Tag" is a string that controllers can use to
recognize bootstrap phases, if they want to do something smarter
than just blindly displaying the summary string; see Section 5
for the current tags that Tor issues.
The StatusSeverity describes whether this is a normal bootstrap
phase (severity notice) or an indication of a bootstrapping
problem (severity warn).
For bootstrap problems, we include the same progress, tag, and
summary values as we would for a normal bootstrap event, but we
also include "warning", "reason", "count", and "recommendation"
key/value combos. The "count" number tells how many bootstrap
problems there have been so far at this phase. The "reason"
string lists one of the reasons allowed in the ORCONN event. The
"warning" argument string with any hints Tor has to offer about
why it's having troubles bootstrapping.
The "reason" values are long-term-stable controller-facing tags to
identify particular issues in a bootstrapping step. The warning
strings, on the other hand, are human-readable. Controllers
SHOULD NOT rely on the format of any warning string. Currently
the possible values for "recommendation" are either "ignore" or
"warn" -- if ignore, the controller can accumulate the string in
a pile of problems to show the user if the user asks; if warn,
the controller should alert the user that Tor is pretty sure
there's a bootstrapping problem.
The "host" value is the identity digest (in hex) of the node we're
trying to connect to; the "hostaddr" is an address:port combination,
where 'address' is an ipv4 or ipv6 address.
Currently Tor uses recommendation=ignore for the first
nine bootstrap problem reports for a given phase, and then
uses recommendation=warn for subsequent problems at that
phase. Hopefully this is a good balance between tolerating
occasional errors and reporting serious problems quickly.
ENOUGH_DIR_INFO
Tor now knows enough network-status documents and enough server
descriptors that it's going to start trying to build circuits now.
[Newer versions of Tor (0.2.6.2-alpha and later):
If the consensus contains Exits (the typical case), Tor will build
both exit and internal circuits. If not, Tor will only build internal
circuits.]
{Controllers may want to use this event to decide when to indicate
progress to their users, but should not interrupt the user's browsing
to tell them so.}
NOT_ENOUGH_DIR_INFO
We discarded expired statuses and server descriptors to fall
below the desired threshold of directory information. We won't
try to build any circuits until ENOUGH_DIR_INFO occurs again.
{Controllers may want to use this event to decide when to indicate
progress to their users, but should not interrupt the user's browsing
to tell them so.}
CIRCUIT_ESTABLISHED
Tor is able to establish circuits for client use. This event will
only be sent if we just built a circuit that changed our mind --
that is, prior to this event we didn't know whether we could
establish circuits.
{Suggested use: controllers can notify their users that Tor is
ready for use as a client once they see this status event. [Perhaps
controllers should also have a timeout if too much time passes and
this event hasn't arrived, to give tips on how to troubleshoot.
On the other hand, hopefully Tor will send further status events
if it can identify the problem.]}
CIRCUIT_NOT_ESTABLISHED
"REASON=" "EXTERNAL_ADDRESS" / "DIR_ALL_UNREACHABLE" / "CLOCK_JUMPED"
We are no longer confident that we can build circuits. The "reason"
keyword provides an explanation: which other status event type caused
our lack of confidence.
{Controllers may want to use this event to decide when to indicate
progress to their users, but should not interrupt the user's browsing
to do so.}
[Note: only REASON=CLOCK_JUMPED is implemented currently.]
CONSENSUS_ARRIVED
Tor has received and validated a new consensus networkstatus.
(This event can be delayed a little while after the consensus
is received, if Tor needs to fetch certificates.)
DANGEROUS_PORT
"PORT=" port
"RESULT=" "REJECT" / "WARN"
A stream was initiated to a port that's commonly used for
vulnerable-plaintext protocols. If the Result is "reject", we
refused the connection; whereas if it's "warn", we allowed it.
{Controllers should warn their users when this occurs, unless they
happen to know that the application using Tor is in fact doing so
correctly (e.g., because it is part of a distributed bundle). They
might also want some sort of interface to let the user configure
their RejectPlaintextPorts and WarnPlaintextPorts config options.}
DANGEROUS_SOCKS
"PROTOCOL=" "SOCKS4" / "SOCKS5"
"ADDRESS=" IP:port
A connection was made to Tor's SOCKS port using one of the SOCKS
approaches that doesn't support hostnames -- only raw IP addresses.
If the client application got this address from gethostbyname(),
it may be leaking target addresses via DNS.
{Controllers should warn their users when this occurs, unless they
happen to know that the application using Tor is in fact doing so
correctly (e.g., because it is part of a distributed bundle).}
SOCKS_UNKNOWN_PROTOCOL
"DATA=string"
A connection was made to Tor's SOCKS port that tried to use it
for something other than the SOCKS protocol. Perhaps the user is
using Tor as an HTTP proxy? The DATA is the first few characters
sent to Tor on the SOCKS port.
{Controllers may want to warn their users when this occurs: it
indicates a misconfigured application.}
SOCKS_BAD_HOSTNAME
"HOSTNAME=QuotedString"
Some application gave us a funny-looking hostname. Perhaps
it is broken? In any case it won't work with Tor and the user
should know.
{Controllers may want to warn their users when this occurs: it
usually indicates a misconfigured application.}
Actions for STATUS_SERVER can be as follows:
EXTERNAL_ADDRESS
"ADDRESS=IP"
"HOSTNAME=NAME"
"METHOD=CONFIGURED/CONFIGURED_ORPORT/DIRSERV/RESOLVED/
INTERFACE/GETHOSTNAME"
Our best idea for our externally visible IP has changed to 'IP'. If
'HOSTNAME' is present, we got the new IP by resolving 'NAME'. If the
method is 'CONFIGURED', the IP was given verbatim as the Address
configuration option. If the method is 'CONFIGURED_ORPORT', the IP was
given verbatim in the ORPort configuration option. If the method is
'RESOLVED', we resolved the Address configuration option to get the IP.
If the method is 'GETHOSTNAME', we resolved our hostname to get the IP.
If the method is 'INTERFACE', we got the address of one of our network
interfaces to get the IP. If the method is 'DIRSERV', a directory
server told us a guess for what our IP might be.
{Controllers may want to record this info and display it to the user.}
CHECKING_REACHABILITY
"ORADDRESS=IP:port"
"DIRADDRESS=IP:port"
We're going to start testing the reachability of our external OR port
or directory port.
{This event could affect the controller's idea of server status, but
the controller should not interrupt the user to tell them so.}
REACHABILITY_SUCCEEDED
"ORADDRESS=IP:port"
"DIRADDRESS=IP:port"
We successfully verified the reachability of our external OR port or
directory port (depending on which of ORADDRESS or DIRADDRESS is
given.)
{This event could affect the controller's idea of server status, but
the controller should not interrupt the user to tell them so.}
GOOD_SERVER_DESCRIPTOR
We successfully uploaded our server descriptor to at least one
of the directory authorities, with no complaints.
{Originally, the goal of this event was to declare "every authority
has accepted the descriptor, so there will be no complaints
about it." But since some authorities might be offline, it's
harder to get certainty than we had thought. As such, this event
is equivalent to ACCEPTED_SERVER_DESCRIPTOR below. Controllers
should just look at ACCEPTED_SERVER_DESCRIPTOR and should ignore
this event for now.}
SERVER_DESCRIPTOR_STATUS
"STATUS=" "LISTED" / "UNLISTED"
We just got a new networkstatus consensus, and whether we're in
it or not in it has changed. Specifically, status is "listed"
if we're listed in it but previous to this point we didn't know
we were listed in a consensus; and status is "unlisted" if we
thought we should have been listed in it (e.g. we were listed in
the last one), but we're not.
{Moving from listed to unlisted is not necessarily cause for
alarm. The relay might have failed a few reachability tests,
or the Internet might have had some routing problems. So this
feature is mainly to let relay operators know when their relay
has successfully been listed in the consensus.}
[Not implemented yet. We should do this in 0.2.2.x. -RD]
NAMESERVER_STATUS
"NS=addr"
"STATUS=" "UP" / "DOWN"
"ERR=" message
One of our nameservers has changed status.
{This event could affect the controller's idea of server status, but
the controller should not interrupt the user to tell them so.}
NAMESERVER_ALL_DOWN
All of our nameservers have gone down.
{This is a problem; if it happens often without the nameservers
coming up again, the user needs to configure more or better
nameservers.}
DNS_HIJACKED
Our DNS provider is providing an address when it should be saying
"NOTFOUND"; Tor will treat the address as a synonym for "NOTFOUND".
{This is an annoyance; controllers may want to tell admins that their
DNS provider is not to be trusted.}
DNS_USELESS
Our DNS provider is giving a hijacked address instead of well-known
websites; Tor will not try to be an exit node.
{Controllers could warn the admin if the relay is running as an
exit node: the admin needs to configure a good DNS server.
Alternatively, this happens a lot in some restrictive environments
(hotels, universities, coffeeshops) when the user hasn't registered.}
BAD_SERVER_DESCRIPTOR
"DIRAUTH=addr:port"
"REASON=string"
A directory authority rejected our descriptor. Possible reasons
include malformed descriptors, incorrect keys, highly skewed clocks,
and so on.
{Controllers should warn the admin, and try to cope if they can.}
ACCEPTED_SERVER_DESCRIPTOR
"DIRAUTH=addr:port"
A single directory authority accepted our descriptor.
// actually notice
{This event could affect the controller's idea of server status, but
the controller should not interrupt the user to tell them so.}
REACHABILITY_FAILED
"ORADDRESS=IP:port"
"DIRADDRESS=IP:port"
We failed to connect to our external OR port or directory port
successfully.
{This event could affect the controller's idea of server status. The
controller should warn the admin and suggest reasonable steps to take.}
HIBERNATION_STATUS
"STATUS=" "AWAKE" | "SOFT" | "HARD"
Our bandwidth based accounting status has changed, and we are now
relaying traffic/rejecting new connections/hibernating.
{This event could affect the controller's idea of server status. The
controller MAY inform the admin, though presumably the accounting was
explicitly enabled for a reason.}
[This event was added in tor 0.2.9.0-alpha.]
```
### Our set of guard nodes has changed { #GUARD }
Syntax:
```text
"650" SP "GUARD" SP Type SP Name SP Status ... CRLF
Type = "ENTRY"
Name = ServerSpec
(Identifies the guard affected)
Status = "NEW" | "UP" | "DOWN" | "BAD" | "GOOD" | "DROPPED"
```
The ENTRY type indicates a guard used for connections to the Tor
network.
The Status values are:
```text
"NEW" -- This node was not previously used as a guard; now we have
picked it as one.
"DROPPED" -- This node is one we previously picked as a guard; we
no longer consider it to be a member of our guard list.
"UP" -- The guard now seems to be reachable.
"DOWN" -- The guard now seems to be unreachable.
"BAD" -- Because of flags set in the consensus and/or values in the
configuration, this node is now unusable as a guard.
"BAD_L2" -- This layer2 guard has expired or got removed from the
consensus. This node is removed from the layer2 guard set.
"GOOD" -- Because of flags set in the consensus and/or values in the
configuration, this node is now usable as a guard.
Controllers must accept unrecognized types and unrecognized statuses.
```
### Network status has changed { #NS }
Syntax:
"650" "+" "NS" CRLF 1\*NetworkStatus "." CRLF "650" SP "OK" CRLF
The event is used whenever our local view of a relay status changes.
This happens when we get a new v3 consensus (in which case the entries
we see are a duplicate of what we see in the NEWCONSENSUS event,
below), but it also happens when we decide to mark a relay as up or
down in our local status, for example based on connection attempts.
\[First added in 0.1.2.3-alpha\]
### Bandwidth used on an application stream { #STREAM_BW }
The syntax is:
```text
"650" SP "STREAM_BW" SP StreamID SP BytesWritten SP BytesRead SP
Time CRLF
BytesWritten = 1*DIGIT
BytesRead = 1*DIGIT
Time = ISOTime2Frac
```
BytesWritten and BytesRead are the number of bytes written and read
by the application since the last STREAM_BW event on this stream.
Note that from Tor's perspective, *reading* a byte on a stream means
that the application *wrote* the byte. That's why the order of "written"
vs "read" is opposite for stream_bw events compared to bw events.
The Time field is provided only in versions 0.3.2.1-alpha and later. It
records when Tor created the bandwidth event.
These events are generated about once per second per stream; no events
are generated for streams that have not written or read. These events
apply only to streams entering Tor (such as on a SOCKSPort, TransPort,
or so on). They are not generated for exiting streams.
### Per-country client stats { #CLIENTS_SEEN }
The syntax is:
```text
"650" SP "CLIENTS_SEEN" SP TimeStarted SP CountrySummary SP
IPVersions CRLF
```
We just generated a new summary of which countries we've seen clients
from recently. The controller could display this for the user, e.g.
in their "relay" configuration window, to give them a sense that they
are actually being useful.
Currently only bridge relays will receive this event, but once we figure
out how to sufficiently aggregate and sanitize the client counts on
main relays, we might start sending these events in other cases too.
TimeStarted is a quoted string indicating when the reported summary
counts from (in UTCS).
The CountrySummary keyword has as its argument a comma-separated,
possibly empty set of "countrycode=count" pairs. For example (without
linebreak),
650-CLIENTS_SEEN TimeStarted="2008-12-25 23:50:43"
CountrySummary=us=16,de=8,uk=8
The IPVersions keyword has as its argument a comma-separated set of
"protocol-family=count" pairs. For example,
IPVersions=v4=16,v6=40
Note that these values are rounded, not exact. The rounding
algorithm is specified in the description of "geoip-client-origins"
in dir-spec.txt.
### New consensus networkstatus has arrived { #NEWCONSENSUS }
The syntax is:
```text
"650" "+" "NEWCONSENSUS" CRLF 1*NetworkStatus "." CRLF "650" SP
"OK" CRLF
```
A new consensus networkstatus has arrived. We include NS-style lines for
every relay in the consensus. NEWCONSENSUS is a separate event from the
NS event, because the list here represents every usable relay: so any
relay *not* mentioned in this list is implicitly no longer recommended.
\[First added in 0.2.1.13-alpha\]
### New circuit buildtime has been set { #BUILDTIMEOUT_SET }
The syntax is:
```text
"650" SP "BUILDTIMEOUT_SET" SP Type SP "TOTAL_TIMES=" Total SP
"TIMEOUT_MS=" Timeout SP "XM=" Xm SP "ALPHA=" Alpha SP
"CUTOFF_QUANTILE=" Quantile SP "TIMEOUT_RATE=" TimeoutRate SP
"CLOSE_MS=" CloseTimeout SP "CLOSE_RATE=" CloseRate
CRLF
Type = "COMPUTED" / "RESET" / "SUSPENDED" / "DISCARD" / "RESUME"
Total = Integer count of timeouts stored
Timeout = Integer timeout in milliseconds
Xm = Estimated integer Pareto parameter Xm in milliseconds
Alpha = Estimated floating point Paredo parameter alpha
Quantile = Floating point CDF quantile cutoff point for this timeout
TimeoutRate = Floating point ratio of circuits that timeout
CloseTimeout = How long to keep measurement circs in milliseconds
CloseRate = Floating point ratio of measurement circuits that are closed
```
A new circuit build timeout time has been set. If Type is "COMPUTED",
Tor has computed the value based on historical data. If Type is "RESET",
initialization or drastic network changes have caused Tor to reset
the timeout back to the default, to relearn again. If Type is
"SUSPENDED", Tor has detected a loss of network connectivity and has
temporarily changed the timeout value to the default until the network
recovers. If type is "DISCARD", Tor has decided to discard timeout
values that likely happened while the network was down. If type is
"RESUME", Tor has decided to resume timeout calculation.
The Total value is the count of circuit build times Tor used in
computing this value. It is capped internally at the maximum number
of build times Tor stores (NCIRCUITS_TO_OBSERVE).
The Timeout itself is provided in milliseconds. Internally, Tor rounds
this value to the nearest second before using it.
\[First added in 0.2.2.7-alpha\]
### Signal received { #SIGNAL }
The syntax is:
"650" SP "SIGNAL" SP Signal CRLF
Signal = "RELOAD" / "DUMP" / "DEBUG" / "NEWNYM" / "CLEARDNSCACHE"
A signal has been received and actions taken by Tor. The meaning of each
signal, and the mapping to Unix signals, is as defined in section 3.7.
Future versions of Tor MAY generate signals other than those listed here;
controllers MUST be able to accept them.
If Tor chose to ignore a signal (such as NEWNYM), this event will not be
sent. Note that some options (like ReloadTorrcOnSIGHUP) may affect the
semantics of the signals here.
Note that the HALT (SIGTERM) and SHUTDOWN (SIGINT) signals do not currently
generate any event.
\[First added in 0.2.3.1-alpha\]
### Configuration changed { #CONF_CHANGED }
The syntax is:
StartReplyLine \*(MidReplyLine) EndReplyLine
```text
StartReplyLine = "650-CONF_CHANGED" CRLF
MidReplyLine = "650-" KEYWORD ["=" VALUE] CRLF
EndReplyLine = "650 OK"
```
Tor configuration options have changed (such as via a SETCONF or RELOAD
signal). KEYWORD and VALUE specify the configuration option that was changed.
Undefined configuration options contain only the KEYWORD.
### Circuit status changed slightly { #CIRC_MINOR }
The syntax is:
```text
"650" SP "CIRC_MINOR" SP CircuitID SP CircEvent [SP Path]
[SP "BUILD_FLAGS=" BuildFlags] [SP "PURPOSE=" Purpose]
[SP "HS_STATE=" HSState] [SP "REND_QUERY=" HSAddress]
[SP "TIME_CREATED=" TimeCreated]
[SP "OLD_PURPOSE=" Purpose [SP "OLD_HS_STATE=" HSState]] CRLF
CircEvent =
"PURPOSE_CHANGED" / ; circuit purpose or HS-related state changed
"CANNIBALIZED" ; circuit cannibalized
Clients MUST accept circuit events not listed above.
```
The "OLD_PURPOSE" field is provided for both PURPOSE_CHANGED and
CANNIBALIZED events. The "OLD_HS_STATE" field is provided whenever
the "OLD_PURPOSE" field is provided and is a hidden-service-related
purpose.
Other fields are as specified in section 4.1.1 above.
\[First added in 0.2.3.11-alpha\]
### Pluggable transport launched { #TRANSPORT_LAUNCHED }
The syntax is:
```text
"650" SP "TRANSPORT_LAUNCHED" SP Type SP Name SP TransportAddress SP Port
Type = "server" | "client"
Name = The name of the pluggable transport
TransportAddress = An IPv4 or IPv6 address on which the pluggable
transport is listening for connections
Port = The TCP port on which it is listening for connections.
A pluggable transport called 'Name' of type 'Type' was launched
successfully and is now listening for connections on 'Address':'Port'.
```
### Bandwidth used on an OR or DIR or EXIT connection { #CONN_BW }
The syntax is:
```text
"650" SP "CONN_BW" SP "ID=" ConnID SP "TYPE=" ConnType
SP "READ=" BytesRead SP "WRITTEN=" BytesWritten CRLF
ConnType = "OR" / ; Carrying traffic within the tor network. This can
either be our own (client) traffic or traffic we're
relaying within the network.
"DIR" / ; Fetching tor descriptor data, or transmitting
descriptors we're mirroring.
"EXIT" ; Carrying traffic between the tor network and an
external destination.
BytesRead = 1*DIGIT
BytesWritten = 1*DIGIT
Controllers MUST tolerate unrecognized connection types.
```
BytesWritten and BytesRead are the number of bytes written and read
by Tor since the last CONN_BW event on this connection.
These events are generated about once per second per connection; no
events are generated for connections that have not read or written.
These events are only generated if TestingTorNetwork is set.
\[First added in 0.2.5.2-alpha\]
### Bandwidth used by all streams attached to a circuit { #CIRC_BW }
The syntax is:
```text
"650" SP "CIRC_BW" SP "ID=" CircuitID SP "READ=" BytesRead SP
"WRITTEN=" BytesWritten SP "TIME=" Time SP
"DELIVERED_READ=" DeliveredBytesRead SP
"OVERHEAD_READ=" OverheadBytesRead SP
"DELIVERED_WRITTEN=" DeliveredBytesWritten SP
"OVERHEAD_WRITTEN=" OverheadBytesWritten SP
"SS=" SlowStartState SP
"CWND=" CWNDCells SP
"RTT=" RTTMilliseconds SP
"MIN_RTT=" RTTMilliseconds CRLF
BytesRead = 1*DIGIT
BytesWritten = 1*DIGIT
OverheadBytesRead = 1*DIGIT
OverheadBytesWritten = 1*DIGIT
DeliveredBytesRead = 1*DIGIT
DeliveredBytesWritten = 1*DIGIT
SlowStartState = 0 or 1
CWNDCells = 1*DIGIT
RTTMilliseconds= 1*DIGIT
Time = ISOTime2Frac
```
BytesRead and BytesWritten are the number of bytes read and written
on this circuit since the last CIRC_BW event. These bytes have not
necessarily been validated by Tor, and can include invalid cells,
dropped cells, and ignored cells (such as padding cells). These
values include the relay headers, but not circuit headers.
Circuit data that has been validated and processed by Tor is further
broken down into two categories: delivered payloads and overhead.
DeliveredBytesRead and DeliveredBytesWritten are the total relay cell
payloads transmitted since the last CIRC_BW event, not counting relay
cell headers or circuit headers. OverheadBytesRead and
OverheadBytesWritten are the extra unused bytes at the end of each
cell in order for it to be the fixed CELL_LEN bytes long.
The sum of DeliveredBytesRead and OverheadBytesRead MUST be less than
BytesRead, and the same is true for their written counterparts. This
sum represents the total relay cell bytes on the circuit that
have been validated by Tor, not counting relay headers and cell headers.
Subtracting this sum (plus relay cell headers) from the BytesRead
(or BytesWritten) value gives the byte count that Tor has decided to
reject due to protocol errors, or has otherwise decided to ignore.
The Time field is provided only in versions 0.3.2.1-alpha and later. It
records when Tor created the bandwidth event.
The SS, CWND, RTT, and MIN_RTT fields are present only if the circuit
has negotiated congestion control to an onion service or Exit hop (any
intermediate leaky pipe congestion control hops are not examined here).
SS provides an indication if the circuit is in slow start (1), or not (0).
CWND is the size of the congestion window in terms of number of cells.
RTT is the N_EWMA smoothed current RTT value, and MIN_RTT is the minimum
RTT value of the circuit. The SS and CWND fields apply only to the
upstream direction of the circuit. The slow start state and CWND values
of the other endpoint may be different.
These events are generated about once per second per circuit; no events
are generated for circuits that had no attached stream writing or
reading.
\[First added in 0.2.5.2-alpha\]
\[DELIVERED_READ, OVERHEAD_READ, DELIVERED_WRITTEN, and OVERHEAD_WRITTEN
were added in Tor 0.3.4.0-alpha\]
\[SS, CWND, RTT, and MIN_RTT were added in Tor 0.4.7.5-alpha\]
### Per-circuit cell stats { #CELL_STATS }
The syntax is:
```text
"650" SP "CELL_STATS"
[ SP "ID=" CircuitID ]
[ SP "InboundQueue=" QueueID SP "InboundConn=" ConnID ]
[ SP "InboundAdded=" CellsByType ]
[ SP "InboundRemoved=" CellsByType SP
"InboundTime=" MsecByType ]
[ SP "OutboundQueue=" QueueID SP "OutboundConn=" ConnID ]
[ SP "OutboundAdded=" CellsByType ]
[ SP "OutboundRemoved=" CellsByType SP
"OutboundTime=" MsecByType ] CRLF
CellsByType, MsecByType = CellType ":" 1*DIGIT
0*( "," CellType ":" 1*DIGIT )
CellType = 1*( "a" - "z" / "0" - "9" / "_" )
Examples are:
650 CELL_STATS ID=14 OutboundQueue=19403 OutboundConn=15
OutboundAdded=create_fast:1,relay_early:2
OutboundRemoved=create_fast:1,relay_early:2
OutboundTime=create_fast:0,relay_early:0
650 CELL_STATS InboundQueue=19403 InboundConn=32
InboundAdded=relay:1,created_fast:1
InboundRemoved=relay:1,created_fast:1
InboundTime=relay:0,created_fast:0
OutboundQueue=6710 OutboundConn=18
OutboundAdded=create:1,relay_early:1
OutboundRemoved=create:1,relay_early:1
OutboundTime=create:0,relay_early:0
```
ID is the locally unique circuit identifier that is only included if the
circuit originates at this node.
Inbound and outbound refer to the direction of relay cell flow through the
circuit which is either to origin (inbound) or from origin (outbound).
InboundQueue and OutboundQueue are identifiers of the inbound and
outbound circuit queues of this circuit. These identifiers are only
unique per OR connection. OutboundQueue is chosen by this node and
matches InboundQueue of the next node in the circuit.
InboundConn and OutboundConn are locally unique IDs of inbound and
outbound OR connection. OutboundConn does not necessarily match
InboundConn of the next node in the circuit.
InboundQueue and InboundConn are not present if the circuit originates
at this node. OutboundQueue and OutboundConn are not present if the
circuit (currently) ends at this node.
InboundAdded and OutboundAdded are total number of cells by cell type
added to inbound and outbound queues. Only present if at least one cell
was added to a queue.
InboundRemoved and OutboundRemoved are total number of cells by
cell type processed from inbound and outbound queues. InboundTime and
OutboundTime are total waiting times in milliseconds of all processed
cells by cell type. Only present if at least one cell was removed from
a queue.
These events are generated about once per second per circuit; no
events are generated for circuits that have not added or processed any
cell. These events are only generated if TestingTorNetwork is set.
\[First added in 0.2.5.2-alpha\]
### Token buckets refilled { #TB_EMPTY }
The syntax is:
```text
"650" SP "TB_EMPTY" SP BucketName [ SP "ID=" ConnID ] SP
"READ=" ReadBucketEmpty SP "WRITTEN=" WriteBucketEmpty SP
"LAST=" LastRefill CRLF
BucketName = "GLOBAL" / "RELAY" / "ORCONN"
ReadBucketEmpty = 1*DIGIT
WriteBucketEmpty = 1*DIGIT
LastRefill = 1*DIGIT
Examples are:
650 TB_EMPTY ORCONN ID=16 READ=0 WRITTEN=0 LAST=100
650 TB_EMPTY GLOBAL READ=93 WRITTEN=93 LAST=100
650 TB_EMPTY RELAY READ=93 WRITTEN=93 LAST=100
```
This event is generated when refilling a previously empty token
bucket. BucketNames "GLOBAL" and "RELAY" keywords are used for the
global or relay token buckets, BucketName "ORCONN" is used for the
token buckets of an OR connection. Controllers MUST tolerate
unrecognized bucket names.
ConnID is only included if the BucketName is "ORCONN".
If both global and relay buckets and/or the buckets of one or more OR
connections run out of tokens at the same time, multiple separate
events are generated.
ReadBucketEmpty (WriteBucketEmpty) is the time in millis that the read
(write) bucket was empty since the last refill. LastRefill is the
time in millis since the last refill.
If a bucket went negative and if refilling tokens didn't make it go
positive again, there will be multiple consecutive TB_EMPTY events for
each refill interval during which the bucket contained zero tokens or
less. In such a case, ReadBucketEmpty or WriteBucketEmpty are capped
at LastRefill in order not to report empty times more than once.
These events are only generated if TestingTorNetwork is set.
\[First added in 0.2.5.2-alpha\]
### HiddenService descriptors { #HS_DESC }
The syntax is:
```text
"650" SP "HS_DESC" SP Action SP HSAddress SP AuthType SP HsDir
[SP DescriptorID] [SP "REASON=" Reason] [SP "REPLICA=" Replica]
[SP "HSDIR_INDEX=" HSDirIndex]
Action = "REQUESTED" / "UPLOAD" / "RECEIVED" / "UPLOADED" / "IGNORE" /
"FAILED" / "CREATED"
HSAddress = 16*Base32Character / 56*Base32Character / "UNKNOWN"
AuthType = "NO_AUTH" / "BASIC_AUTH" / "STEALTH_AUTH" / "UNKNOWN"
HsDir = LongName / Fingerprint / "UNKNOWN"
DescriptorID = 32*Base32Character / 43*Base64Character
Reason = "BAD_DESC" / "QUERY_REJECTED" / "UPLOAD_REJECTED" / "NOT_FOUND" /
"UNEXPECTED" / "QUERY_NO_HSDIR" / "QUERY_RATE_LIMITED"
Replica = 1*DIGIT
HSDirIndex = 64*HEXDIG
These events will be triggered when required HiddenService descriptor is
not found in the cache and a fetch or upload with the network is performed.
If the fetch was triggered with only a DescriptorID (using the HSFETCH
command for instance), the HSAddress only appears in the Action=RECEIVED
since there is no way to know the HSAddress from the DescriptorID thus
the value will be "UNKNOWN".
If we already had the v0 descriptor, the newly fetched v2 descriptor
will be ignored and a "HS_DESC" event with "IGNORE" action will be
generated.
For HsDir, LongName is always preferred. If HsDir cannot be found in node
list at the time event is sent, Fingerprint will be used instead.
If Action is "FAILED", Tor SHOULD send Reason field as well. Possible
values of Reason are:
- "BAD_DESC" - descriptor was retrieved, but found to be unparsable.
- "QUERY_REJECTED" - query was rejected by HS directory.
- "UPLOAD_REJECTED" - descriptor was rejected by HS directory.
- "NOT_FOUND" - HS descriptor with given identifier was not found.
- "UNEXPECTED" - nature of failure is unknown.
- "QUERY_NO_HSDIR" - No suitable HSDir were found for the query.
- "QUERY_RATE_LIMITED" - query for this service is rate-limited
For "QUERY_NO_HSDIR" or "QUERY_RATE_LIMITED", the HsDir will be set to
"UNKNOWN" which was introduced in tor 0.3.1.0-alpha and 0.4.1.0-alpha
respectively.
If Action is "CREATED", Tor SHOULD send Replica field as well. The Replica
field contains the replica number of the generated descriptor. The Replica
number is specified in rend-spec.txt section 1.3 and determines the
descriptor ID of the descriptor.
For hidden service v3, the following applies:
The "HSDIR_INDEX=" is an optional field that is only for version 3
which contains the computed index of the HsDir the descriptor was
uploaded to or fetched from.
The "DescriptorID" key is the descriptor blinded key used for the index
value at the "HsDir".
The "REPLICA=" field is not used for the "CREATED" event because v3
doesn't use the replica number in the descriptor ID computation.
Because client authentication is not yet implemented, the "AuthType"
field is always "NO_AUTH".
[HS v3 support added 0.3.3.1-alpha]
```
### HiddenService descriptors content { #HS_DESC_CONTENT }
The syntax is:
```text
"650" "+" "HS_DESC_CONTENT" SP HSAddress SP DescId SP HsDir CRLF
Descriptor CRLF "." CRLF "650" SP "OK" CRLF
HSAddress = 16*Base32Character / 56*Base32Character / "UNKNOWN"
DescId = 32*Base32Character / 32*Base64Character
HsDir = LongName / "UNKNOWN"
Descriptor = The text of the descriptor formatted as specified in
rend-spec.txt section 1.3 (v2) or rend-spec-v3.txt
section 2.4 (v3) or empty string on failure.
```
This event is triggered when a successfully fetched HS descriptor is
received. The text of that descriptor is then replied. If the HS_DESC
event is enabled, it is replied just after the RECEIVED action.
If a fetch fails, the Descriptor is an empty string and HSAddress is set
to "UNKNOWN". The HS_DESC event should be used to get more information on
the failed request.
If the fetch fails for the QUERY_NO_HSDIR or QUERY_RATE_LIMITED reason from
the HS_DESC event, the HsDir is set to "UNKNOWN". This was introduced in
0.3.1.0-alpha and 0.4.1.0-alpha respectively.
It's expected to receive a reply relatively fast as in it's the time it
takes to fetch something over the Tor network. This can be between a
couple of seconds up to 60 seconds (not a hard limit). But, in any cases,
this event will reply either the descriptor's content or an empty one.
\[HS_DESC_CONTENT was added in Tor 0.2.7.1-alpha\]
\[HS v3 support added 0.3.3.1-alpha\]
### Network liveness has changed { #NETWORK_LIVENESS }
Syntax:
```text
"650" SP "NETWORK_LIVENESS" SP Status CRLF
Status = "UP" / ; The network now seems to be reachable.
"DOWN" / ; The network now seems to be unreachable.
Controllers MUST tolerate unrecognized status types.
[NETWORK_LIVENESS was added in Tor 0.2.7.2-alpha]
```
### Pluggable Transport Logs { #PT_LOG }
Syntax:
"650" SP "PT_LOG" SP PT=Program SP Message
```text
Program = The program path as defined in the *TransportPlugin
configuration option. Tor accepts relative and full path.
Message = The log message that the PT sends back to the tor parent
process minus the "LOG" string prefix. Formatted as
specified in pt-spec.txt section "3.3.4. Pluggable
Transport Log Message".
This event is triggered when tor receives a log message from the PT.
Example:
PT (obfs4): LOG SEVERITY=debug MESSAGE="Connected to bridge A"
the resulting control port event would be:
Tor: 650 PT_LOG PT=/usr/bin/obs4proxy SEVERITY=debug MESSAGE="Connected to bridge A"
[PT_LOG was added in Tor 0.4.0.1-alpha]
```
### Pluggable Transport Status { #PT_STATUS }
Syntax:
"650" SP "PT_STATUS" SP PT=Program SP TRANSPORT=Transport SP Message
```text
Program = The program path as defined in the *TransportPlugin
configuration option. Tor accepts relative and full path.
Transport = This value indicates a hint on what the PT is such as the
name or the protocol used for instance.
Message = The status message that the PT sends back to the tor parent
process minus the "STATUS" string prefix. Formatted as
specified in pt-spec.txt section "3.3.5 Pluggable
Transport Status Message".
This event is triggered when tor receives a log message from the PT.
Example:
PT (obfs4): STATUS TRANSPORT=obfs4 CONNECT=Success
the resulting control port event would be:
Tor: 650 PT_STATUS PT=/usr/bin/obs4proxy TRANSPORT=obfs4 CONNECT=Success
[PT_STATUS was added in Tor 0.4.0.1-alpha]
```