aboutsummaryrefslogtreecommitdiff
path: root/spec/control-spec/replies.md
blob: ed76cbd4e16f515458b7188ac3f3cda679d5fa35 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
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]
```