aboutsummaryrefslogtreecommitdiff
path: root/spec/control-spec/replies.md
diff options
context:
space:
mode:
Diffstat (limited to 'spec/control-spec/replies.md')
-rw-r--r--spec/control-spec/replies.md1796
1 files changed, 1796 insertions, 0 deletions
diff --git a/spec/control-spec/replies.md b/spec/control-spec/replies.md
new file mode 100644
index 0000000..ed76cbd
--- /dev/null
+++ b/spec/control-spec/replies.md
@@ -0,0 +1,1796 @@
+<a id="control-spec.txt-4"></a>
+
+# 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.
+
+<a id="control-spec.txt-4.1"></a>
+
+## 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".
+
+<a id="control-spec.txt-4.1.1"></a>
+
+### 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.]
+```
+
+<a id="control-spec.txt-4.1.2"></a>
+
+### 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.
+```
+
+<a id="control-spec.txt-4.1.3"></a>
+
+### 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]
+```
+
+<a id="control-spec.txt-4.1.4"></a>
+
+### 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).\]
+
+<a id="control-spec.txt-4.1.5"></a>
+
+### 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.
+
+<a id="control-spec.txt-4.1.6"></a>
+
+### 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
+```
+
+<a id="control-spec.txt-4.1.7"></a>
+
+### 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 / "<error>"
+ 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.
+
+<a id="control-spec.txt-4.1.8"></a>
+
+### 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.)
+
+<a id="control-spec.txt-4.1.9"></a>
+
+### Our descriptor changed { #DESCCHANGED }
+
+Syntax:
+
+"650" SP "DESCCHANGED" CRLF
+
+\[First added in 0.1.2.2-alpha.\]
+
+<a id="control-spec.txt-4.1.10"></a>
+
+### 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.]
+```
+
+<a id="control-spec.txt-4.1.11"></a>
+
+### 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.
+```
+
+<a id="control-spec.txt-4.1.12"></a>
+
+### 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\]
+
+<a id="control-spec.txt-4.1.13"></a>
+
+### 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.
+
+<a id="control-spec.txt-4.1.14"></a>
+
+### 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.
+
+<a id="control-spec.txt-4.1.15"></a>
+
+### 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\]
+
+<a id="control-spec.txt-4.1.16"></a>
+
+### 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\]
+
+<a id="control-spec.txt-4.1.17"></a>
+
+### 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\]
+
+<a id="control-spec.txt-4.1.18"></a>
+
+### 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.
+
+<a id="control-spec.txt-4.1.19"></a>
+
+### 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\]
+
+<a id="control-spec.txt-4.1.20"></a>
+
+### 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'.
+```
+
+<a id="control-spec.txt-4.1.21"></a>
+
+### 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\]
+
+<a id="control-spec.txt-4.1.22"></a>
+
+### 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 relay message bodies,
+and overhead.
+DeliveredBytesRead and DeliveredBytesWritten are the total
+length of the relay message bodies
+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\]
+
+<a id="control-spec.txt-4.1.23"></a>
+
+### 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\]
+
+<a id="control-spec.txt-4.1.24"></a>
+
+### 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\]
+
+<a id="control-spec.txt-4.1.25"></a>
+
+### 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]
+```
+
+<a id="control-spec.txt-4.1.26"></a>
+
+### 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\]
+
+<a id="control-spec.txt-4.1.27"></a>
+
+### 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]
+```
+
+<a id="control-spec.txt-4.1.28"></a>
+
+### 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]
+```
+
+<a id="control-spec.txt-4.1.29"></a>
+
+### 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]
+```