aboutsummaryrefslogtreecommitdiff
path: root/proposals/312-relay-auto-ipv6-addr.txt
blob: 752a0be1e4307d300088eaace749c2ab04616bc4 (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
Filename: 312-relay-auto-ipv6-addr.txt
Title: Tor Relays Automatically Find Their IPv6 Address
Author: teor, Nick Mathewson
Created: 28-January-2020
Status: Draft
Ticket: #33073

0. Abstract

   We propose that Tor relays (and bridges) should automatically find their
   IPv6 address.

   Like tor's existing IPv4 address auto-detection, the chosen IPv6 address
   will be published as an IPv6 ORPort in the relay's descriptor. Clients,
   relays, and authorities connect to relay descriptor IP addresses.
   Therefore, IP addresses in descriptors need to be publicly routable. (If
   the relay is running on the public tor network.)

   To discover their IPv6 address, some relays may fetch directory documents
   over IPv6. (For anonymity reasons, bridges are unable to fetch directory
   documents over IPv6, until clients start to do so.)

1. Introduction

   Tor relays (and bridges) currently find their IPv4 address, and use it as
   their ORPort and DirPort address when publishing their descriptor. But
   relays and bridges do not automatically find their IPv6 address.

   However, relay operators can manually configure an ORPort with an IPv6
   address, and that ORPort is published in their descriptor in an "or-address"
   line (see [Tor Directory Protocol]).

   Many relay operators don't know their relay's IPv4 or IPv6 addresses. So
   they rely on Tor's IPv4 auto-detection, and don't configure an IPv6
   address. When operators do configure an IPv6 address, it's easy for them to
   make mistakes. IPv6 ORPort issues are a significant source of relay
   operator support requests.

   Implementing IPv6 address auto-detection, and IPv6 ORPort reachability
   checks (see [Proposal 311: Relay IPv6 Reachability]) will increase the
   number of working IPv6-capable relays in the tor network.

2. Scope

   This proposal modifies Tor's behaviour as follows:

   Relays, bridges, and directory authorities:
     * automatically find their IPv6 address, and
     * for consistency between IPv4 and IPv6 detection:
       * start using IPv4 ORPort and DirPort for IPv4 address detection, and
       * re-order IPv4 address detection methods.

   Relays and directory authorities (but not bridges):
     * fetch some directory documents over IPv6.
   For anonymity reasons, bridges are unable to fetch directory documents over
   IPv6, until clients start to do so. (See
   [Proposal 306: Client Auto IPv6 Connections].)

   This proposal makes a small, optional change to existing client behaviour:
     * clients also check IPv6 addresses when rotating TLS keys for new
       networks.
   In addition to the changes to IPv4 address resolution, most of which won't
   affect clients. (Because they do not set Address, ORPort, or DirPort.)

   Throughout this proposal, "relays" includes directory authorities, except
   where they are specifically excluded. "relays" does not include bridges,
   except where they are specifically included. (The first mention of "relays"
   in each section should specifically exclude or include these other roles.)

   When this proposal describes Tor's current behaviour, it covers all
   supported Tor versions (0.3.5.7 to 0.4.2.5), as of January 2020, except
   where another version is specifically mentioned.

3. Finding Relay IPv6 Addresses

   We propose that Tor relays (and bridges) should automatically find their
   IPv6 address.

   Like tor's existing IPv4 address auto-detection, the chosen IPv6 address
   will be published as an IPv6 ORPort in the relay's descriptor. Clients,
   relays, and authorities connect to relay descriptor IP addresses.
   Therefore, IP addresses in descriptors need to be publicly routable. (If
   the relay is running on the public tor network.)

   Relays should ignore any addresses that are reserved for private networks,
   and check the reachability of addresses that appear to be public (see
   [Proposal 311: Relay IPv6 Reachability]). Relays should only publish IP
   addresses in their descriptor, if they are public and reachable. (If the
   relay is not running on the public tor network, it may use any IP address.)

   To discover their IPv6 address, some relays may fetch directory documents
   over IPv6. (For anonymity reasons, bridges are unable to fetch directory
   documents over IPv6, until clients start to do so.)

3.1. Current Relay IPv4 Address Implementation

   Currently, all relays (and bridges) must have an IPv4 address. IPv6
   addresses are optional for relays.

   Tor currently tries to find relay IPv4 addresses in this order:
     1. the Address torrc option
     2. the address of the hostname (resolved using DNS, if needed)
     3. a local interface address
        (by making a self-connected socket, if needed)
     4. an address reported by a directory server (using X-Your-Address-Is)

   When using the Address option, or the hostname, tor supports:
     * an IPv4 address literal, or
     * resolving an IPv4 address from a hostname.

   If tor is running on the public network, and an address isn't globally
   routable, tor ignores it. (If it was explicitly set in Address, tor logs an
   error.)

   If there are multiple valid addresses, tor chooses:
     * the first address returned by the resolver,
     * the first address returned by the local interface API, and
     * the latest address(es) returned by a directory server, DNS, or the
       local interface API.

3.2. Finding Relay IPv6 Addresses

   We propose that relays (and bridges) try to find their IPv6 address. For
   consistency, we also propose to change the address resolution order for
   IPv4 addresses.

   We use the following general principles to choose the order of IP address
   methods:
     * Explicit is better than Implicit,
     * Local Information is better than a Remote Dependency,
     * Trusted is better than Untrusted, and
     * Reliable is better than Unreliable.
   Within these constraints, we try to find the simplest working design.

   If a relay is given the wrong address by an attacker, the attacker can
   direct all inbound relay traffic to their own address. They can't decrypt
   the traffic without the relay's private keys, but they can monitor traffic
   patterns.

   Therefore, we only use untrusted address discovery methods, if every other
   method has failed. Any method that uses DNS is potentially untrusted,
   because DNS is often a remote, unauthenticated service. And addresses
   provided by other directory servers are also untrusted.

   Based on these principles, we propose that tor tries to find relay IPv4 and
   IPv6 addresses in this order:
     1. the Address torrc option
     2. the advertised ORPort address
     3. the advertised DirPort address (IPv4 only; relays, not bridges)
     4. a local interface address
        (by making a self-connected socket, if needed)
     5. the address of the host's own hostname (resolved using DNS, if needed)
     6. an address reported by a directory server (using X-Your-Address-Is)

   (Each of these address resolution steps is described in more detail, in its
   own subsection.)

   While making these changes, we want to preserve tor's existing behaviour:
     * resolve Address using the local resolver, if needed,
     * ignore private addresses on public tor networks, and
     * when there are multiple valid addresses:
       * if a list of addresses is received, choose the first address, and
       * if different addresses are received over time, choose the most recent
         address.

3.2.1. Make the Address torrc Option Support IPv6

   First, we propose that relays (and bridges) use the Address torrc option
   to find their IPv4 and IPv6 addresses.

   There are two cases we need to cover:

     1. Explicit IP addresses:
        * allow the option to be specified up to two times,
        * use the IPv4 address for IPv4,
        * use the IPv6 address for IPv6.
        Configuring two addresses in the same address family is a config error.

     2. Hostnames / DNS names:
        * allow the option to be specified up to two times,
        * look up the configured name,
        * use the first IPv4 and IPv6 address returned by the resolver, and
        Resolving multiple addresses in the same address family is not a
        runtime error, but only the first address from each family will be
        used.

   These lookups should ignore private addresses on public tor networks. If
   multiple IPv4 or IPv6 addresses are returned, the first public address from
   each family should be used.

   We should also support the following combinations:
     A. IPv4 Address / hostname (for IPv6 only),
     B. IPv6 Address / hostname (for IPv4 only),
     C. IPv4 Address only / try to guess IPv6, then check its reachability
        (see section 4.3.1 in [Proposal 311: Relay IPv6 Reachability]), and
     D. IPv6 Address only / guess IPv4, then its reachability must succeed.
   There are also similar configurations where a hostname is configured, but it
   only provides IPv4 or IPv6 addresses.

   Combination C is the most common legacy configuration. We want to
   support the following outcomes for legacy configurations:
     * automatic upgrades to guessed and reachable IPv6 addresses,
     * continuing to operate on IPv4 when the IPv6 address can't be guessed,
       and
     * continuing to operate on IPv4 when the IPv6 address has been guessed,
       but it is unreachable.

   At this time, we do not propose guessing multiple IPv4 or IPv6 addresses
   and testing their reachability (see section 3.4.2).

   It is an error to configure an Address option with a private IPv4 or IPv6
   address. Tor should warn if a configured Address hostname does not resolve
   to any publicly routable IPv4 or IPv6 addresses. (In both these cases, if
   tor is configured with a custom set of directory authorities, private
   addresses should be allowed, with a notice-level log.)

   If the Address option is not configured for IPv4 or IPv6, or the hostname
   lookups do not provide both IPv4 and IPv6 addresses, address resolution
   should go to the next step.

3.2.2. Use the Advertised ORPort IPv4 and IPv6 Addresses

   Next, we propose that relays (and bridges) use the first advertised ORPort
   IPv4 and IPv6 addresses, as configured in their torrc.

   The ORPort address may be a hostname. If it is, tor should try to use it to
   resolve an IPv4 and IPv6 address, and open ORPorts on the first available
   IPv4 and IPv6 address. Tor should respect the IPv4Only and IPv6Only port
   flags, if specified. (Tor currently resolves IPv4 addresses in ORPort
   lines. It might not look for an IPv6 address.)

   Relays (and bridges) currently use the first advertised ORPort IPv6 address
   as their IPv6 address. We propose to use the first advertised IPv4 ORPort
   address in a similar way, for consistency.

   Therefore, this change may affect existing relay IPv4 addressses. We expect
   that a small number of relays may change IPv4 address, from a guessed IPv4
   address, to their first advertised IPv4 ORPort address.

   In rare cases, relays may have been using non-advertised ORPorts for their
   addresses. This change may also change their addresses.

   For the purposes of address resolution, tor should ignore private
   configured ORPort addresses on public tor networks. (Binding to private
   ORPort addresses is supported, even on public tor networks, for relays that
   use NAT to reach the Internet.) If an ORPort address is private, address
   resolution should go to the next step.

3.2.3. Use the Advertised DirPort IPv4 Address

   Next, we propose that relays use the first advertised DirPort IPv4 address,
   as configured in their torrc.

   The following DirPort configurations can not be used for address
   resolution, because they are not supported:
     * bridge DirPorts, and
     * advertised IPv6 DirPorts.

   The DirPort address may be a hostname. If it is, tor should try to use it to
   resolve an IPv4 address, and open a DirPort on the first available IPv4
   address. Tor should only look for IPv6 addresses if the IPv6Only port flag
   is specified. (Since advertised IPv6 DirPorts are not supported, a
   working configuration may also require the NoAdvertise flag.)

   Relays currently use the first advertised ORPort IPv6 address as their IPv6
   address. We propose to use the first advertised IPv4 DirPort address in a
   similar way, for consistency.

   Therefore, this change may affect existing relay IPv4 addressses. We expect
   that a very small number of relays may change IPv4 address, from a guessed
   IPv4 address, to their first advertised IPv4 DirPort address. (But we expect
   that most relays that change will be using their ORPort address.)

   For the purposes of address resolution, tor should also ignore private
   configured DirPort addresses on public tor networks. (See the previous
   section for details.) If a DirPort address is private, address resolution
   should go to the next step.

3.2.4. Use Local Interface IPv6 Address

   Next, we propose that relays (and bridges) use publicly routable addresses
   from the OS interface addresses or routing table, as their IPv4 and IPv6
   addresses.

   Tor has local interface address resolution functions, which support most
   major OSes. Tor uses these functions to guess its IPv4 address. We propose
   using them to also guess tor's IPv6 address.

   We also propose modifying the address resolution order, so interface
   addresses are used before the local hostname. This decision is based
   on our principles: interface addresses are local, trusted, and reliable;
   hostname lookups may be remote, untrusted, and unreliable.

   Some developer documentation also recommends using interface addresses,
   rather than resolving the host's own hostname. For example, on recent
   versions of macOS, the man pages tell developers to use interface addresses
   (getifaddrs) rather than look up the host's own hostname (gethostname and
   getaddrinfo). Unfortunately, these man pages don't seem to be available
   online, except for short quotes (see [getaddrinfo man page] for the
   relevant quote).

   If the local interface addresses are unavailable, tor opens a self-connected
   UDP socket to a publicly routable address, but doesn't actually send any
   packets. Instead, it uses the socket APIs to discover the interface address
   for the socket.

   Tor already ignores private IPv4 interface addresses on public relays.
   (Binding to private DirPort addresses is supported, for networks that use
   NAT.) We propose to also ignore private IPv6 interface addresses. If all
   IPv4 or IPv6 interface addresses are private, address resolution should go
   to the next step.

3.2.5. Use Own Hostname IPv6 Addresses

   Next, we propose that relays (and bridges) get their local hostname, look
   up its addresses, and use them as its IPv4 and IPv6 addresses.

   We propose to use the same underlying lookup functions to look up the IPv4
   and IPv6 addresses for:
     * the Address torrc option (see section 3.2.1), and
     * the local hostname.
   However, OS APIs typically only return a single hostname.

   Even though the hostname lookup may use remote DNS, we propose to use it on
   directory authorities, to maintain compatibility with current
   configurations. Even if it is remote, we expect the configured DNS to be
   somewhat trusted by the operator.

   The hostname lookup should ignore private addresses on public relays. If
   multiple IPv4 or IPv6 addresses are returned, the first public address from
   each family should be used. If all IPv4 or IPv6 hostname addresses are
   private, address resolution should go to the next step.

3.2.6. Use Directory Header IPv6 Addresses

   Finally, we propose that relays get their IPv4 and IPv6 addresses from the
   X-Your-Address-Is HTTP header in tor directory documents. To support this
   change, we propose that relays start fetching directory documents over IPv4
   and IPv6.

   We propose that bridges continue to only fetch directory documents over
   IPv4, because they try to imitate clients. (Most clients only fetch
   directory documents over IPv4, a few clients are configured to only fetch
   over IPv6.) When client behaviour changes to use both IPv4 and IPv6 for
   directory fetches, bridge behaviour can also change to match. (See
   section 3.4.1 and [Proposal 306: Client Auto IPv6 Connections].)

   We propose that directory authorities should ignore addresses in directory
   headers. Allowing other authorities (or relays) to change a directory
   authority's published IP address may lead to security issues. Instead,
   if interface and hostname lookups fail, tor should stop address resolution,
   and return a permanent error. (And issue a log to the operator, see below.)

   We propose to use a simple load balancing scheme for IPv4 and IPv6
   directory requests:
     * choose between IPv4 and IPv6 directory requests at random.

   We do not expect this change to have any load-balancing impact on the public
   tor network, because the number of relays is much smaller than the number
   of clients. However, the 6 directory authorities with IPv6 enabled may see
   slightly more directory load, particularly over IPv6.

   To support this change, tor should also change how it handles IPv6
   directory failures on relays:
     * avoid recording IPv6 directory failures as remote relay failures,
       because they may actually be due to a lack of IPv6 connectivity on the
       local relay, and
     * issue IPv6 directory failure logs at notice level, and rate-limit them
       to one per hour.

   If a relay is:
     * explicitly configured with an IPv6 address, or
     * a publicly routable, reachable IPv6 address is discovered in an
       earlier step,
   tor should start issuing IPv6 directory failure logs at warning level.

   (Alternately, tor could stop doing IPv6 directory requests entirely. But we
   prefer designs where all relays behave in a similar way, regardless of their
   internal state.)

   For some more complex directory load-balancing schemes, see section 3.5.3.

   Tor already ignores private IPv4 addresses in directory headers. We propose
   to also ignore private IPv6 addresses in directory headers. If all IPv4 and
   IPv6 addresses in directory headers are private, address resolution should
   pause, and return a temporary error.

   Whenever address resolution fails, tor should warn the operator to set the
   Address torrc option for IPv4 and IPv6. (If IPv4 is available, and only
   IPv6 is missing, the log should be at notice level.)

   Address resolution should continue the next time tor receives a directory
   header containing a public IPv4 or IPv6 address.

3.2.7. Disabling IPv6 Address Resolution

   Relays (and bridges) that have a reachable IPv6 address, but that address
   is unsuitable for the relay, need to be able to disable IPv6 address
   resolution.

   Based on [Proposal 311: Relay IPv6 Reachability], and this proposal, those
   relays would:
     * discover their IPv6 address,
     * open an IPv6 ORPort,
     * find it reachable,
     * publish a descriptor containing that IPv6 ORPort,
     * have the directory authorities find it reachable,
     * have it published in the consensus, and
     * have it used by clients.

   Currently, relays are required to have an IPv4 address. So if the guessed
   IPv4 address is unsuitable, operators can set the Address option to a
   suitable IPv4 address. But IPv6 addresses are optional, so relay operators
   may need to disable IPv6 entirely.

   We propose a new torrc-only option, AddressDisableIPv6. This option is set
   to 0 by default. If the option is set to 1, tor disables IPv6 address
   resolution, IPv6 ORPorts, IPv6 reachability checks, and publishing an IPv6
   ORPort in its descriptor.

3.2.7.1. Disabling IPv6 Address Resolution: Alternative Design

   As an alternative design, tor could change its interpretation of the
   IPv4Only flag, so that the following configuration lines disable IPv6:
   (In the absence of any non-IPv4Only  ORPort lines.)
     * ORPort 9999 IPv4Only
     * ORPort 1.1.1.1:9999 IPv4Only

   However, we believe that this is a confusing design, because we want to
   enable IPv6 address resolution on this similar, very common configuration:
     * ORPort 1.1.1.1:9999

   Therefore, we avoid this design, becuase it changes the meaning of existing
   flags and options.

3.2.8. Automatically Enabling an IPv6 ORPort

   We propose that relays (and bridges) that discover their IPv6 address,
   should open an ORPort on that address, and test its reachability (see
   [Proposal 311: Relay IPv6 Reachability], particularly section 4.3.1).

   The ORPort should be opened on the port configured in the relay's ORPort
   torrc option. Relay operators can use the IPv4Only and IPv6Only options
   to configure different ports for IPv4 and IPv6.

   If an ORPort is configured, but there is no specific bind address, relays
   may attempt to bind to all IPv4 and IPv6 addresses (or all interfaces).
   Some operating systems expect applications to bind to IPv4 and IPv6
   addresses using separate API calls. Others don't support binding only to
   IPv4 or IPv6, and will bind to all addresses whenever there is no specified
   IP address (in a single API call). Tor should support both styles of
   networking API.

   If both reachability checks succeed, relays should publish their IPv4 and
   IPv6 ORPorts in their descriptor.

   If only the IPv4 ORPort check succeeds, and the IPv6 address was guessed
   (rather than being explicitly configured), then relays should:
     * publish their IPv4 ORPort in their descriptor,
     * stop publishing their IPv6 ORPort in their descriptor, and
     * log a notice about the failed IPv6 ORPort reachability check.

3.3. Consequential Tor Client Changes

   We do not propose any required client address resolution changes at this
   time.

   However, clients will use the updated address resolution functions to detect
   when they are on a new connection, and therefore need to rotate their TLS
   keys.

   This minor client change allows us to avoid keeping an outdated version of
   the address resolution functions, which is only for client use.

   Clients should skip address resolution steps that don't apply to them, such
   as:
     * the ORPort option,
     * the DirPort option, and
     * the Address option, if it becomes a relay module option.

3.4. Alternative Address Resolution Designs

   We briefly mention some potential address resolution designs, and the
   reasons that they were not used in this proposal.

   (Some designs may be proposed for future Tor versions, but are not necessary
   at this time.)

3.4.1. Future Bridge IPv6 Address Resolution Behaviour

   When clients automatically fetch directory documents via relay IPv4 and
   IPv6 ORPorts by default, bridges should also adopt this dual-stack
   behaviour. (For example, see [Proposal 306: Client Auto IPv6 Connections].)

   When bridges fetch directory documents via IPv6, they will be able to find
   their IPv6 address using directory headers (see 3.2.6).

3.4.2. Guessing Muliple IPv4 or IPv6 Addresses

   We avoid designs which guess (or configure) multiple IPv4 or IPv6
   addresses, test them all for reachability, and choose one that works.

   Using multiple addresses is rare, and the code to handle it is complex. It
   also requires careful design to avoid:
     * conflicts between multiple relays (or bridges) on the same address
       (tor allows up to 2 relays per IPv4 address),
     * relay flapping,
     * race conditions, and
     * relay address switching.

3.4.3. Rejected Address Resolution Designs

   We reject designs that try all the different address resolution methods,
   score addresses, and then choose the address with the highest score.

   These designs are a generalisation of designs that try different methods in
   a set order (like this proposal). They are more complex than required.
   Complex designs can confuse operators, particularly when they fail.

   Operators should not need complex address resolution in tor: most relay
   (and bridge) addresses are fixed, or change occasionally. And most relays
   can reliably discover their address using directory headers, if all other
   methods fail. (Bridges won't discover their IPv6 address from directory
   headers, see section 3.2.6.)

   If complex address resolution is required, it can be configured using a
   dynamic DNS name in the Address torrc option, or via the control port.

   We also avoid designs that use any addresses other than the first
   (or latest) valid IPv4 and IPv6 address. These designs are more complex, and
   they don't have clear benefits:
     * sort addresses numerically (avoid address flipping)
     * sort addresses by length, then numerically
       (also minimise consensus size)
     * store a list of previous addresses in the state file, and use the most
       recently used address that's currently available.
   Operators who want to avoid address flipping should set the Address option
   in the torrc. Operators who want to minimise the size of the consensus
   should use all-zero IPv6 host identifiers.

3.5. Optional Efficiency and Reliability Changes

   We propose some optional changes for efficiency and reliability, and
   describe their impact.

   Some of these changes may be more appropriate in future releases, or
   along with other proposed features.

3.5.1. Only Use Authenticated Directory Header IPv4 and IPv6 Addresses

   We propose this optional change, to improve relay (and bridge) address
   accuracy and reliability.

   Relays should only use authenticated directory fetches to discover their
   own IPv4 and IPv6 addresses.

   Tor supports authenticated, encrypted directory fetches using BEGINDIR over
   ORPorts (see the [Tor Specification] for details).

   Relays currently fetch unencrypted directory documents over DirPorts. The
   directory document itself is signed, but the HTTP headers are not
   authenticated. (Clients and bridges only fetch directory documents using
   authenticated directory fetches.)

   Using authenticated directory headers for relay addresses:
     * avoids caches (or other machines) mangling X-Your-Address-Is headers in
       transit, and
     * avoids attacks where directories are deliberately given an incorrect IP
       address.

   To make this change, we need to modify two different parts of tor:
     * when making directory requests, relays should fetch some directory
       documents using BEGINDIR over ORPorts, and
     * when using the X-Your-Address-Is HTTP header to guess their own IPv4 or
       IPv6 addresses, relays ignore directory documents that were not fetched
       using BEGINDIR over ORPorts.

   See also sections 3.5.2 (for preferring addresses from directory
   authorities) and 3.5.3 (for load-balancing).

3.5.2. Preferring IPv4 and IPv6 Addresses from Directory Authorities

   We propose this optional change, to improve relay (and bridge) address
   accuracy and reliability.

   Relays store the latest IPv4 and IPv6 addresses received from:
     * a directory authority, and
     * a directory mirror,
   and prefer the address from a directory authority, as long as it is not
   too old.

   Relays should also store a timestamp for each address, and ignore addresses
   where:
     * the timestamp is too old, or
     * the timestamp for the preferred address (from a directory authority)
       is much older than the timestamp for the other address (from a directory
       mirror).

   Relays should try directory authorities often enough, that their addresses
   usually do not become too old. (And if the addresses do become too old,
   relays should try directory authorities more often.)

   As an alternative, relays could ignore addresses from other relays:
     * when using the X-Your-Address-Is HTTP header to guess their own IPv4 or
       IPv6 addresses, relays ignore directory documents that were not fetched
       from directory authorities.
   However, this implementation is not ideal, because it is better for a relay
   to use an address from a directory mirror, than have no address at all.

   See also sections 3.5.1 (for only using addresses from authenticated
   connections) and 3.5.3 (for load-balancing).

3.5.3. Load Balancing

   We propose some optional changes to improve load-balancing.

3.5.3.1. Directory Authority Load Balancing

   Ideally, we would like all relays (and bridges) to do frequent directory
   fetches:
     * using BEGINDIR over ORPorts,
     * to directory authorities.
   However, this change may be unsustainable during high network load
   (see [Ticket 33018: Dir auths using an unsustainable 400+ mbit/s]).

   Therefore, we propose a simple load-balancing scheme between address
   resolution and non-address resolution requests:
     * when relays do not know their own IP addresses, they should make as many
       directory authority ORPort directory fetches as is sustainable, and
     * when relays know their own IP addresses, they should make an occasional
       directory authority ORPort directory fetch, to learn if their address
       has changed.

   We use the load-balancing criteria in section 3.5.3.3, to select the ratio
   between:
     * ORPort connections to directory authorities, and
     * ORPort or DirPort connections to directory mirrors.

   It should be possible for relays to choose between ORPort and DirPort
   connections to directory mirrors at random: they typically have enough spare
   CPU and bandwidth.

   See also sections 3.5.1 (for only using addresses from authenticated
   connections) and 3.5.2 (for preferring addresses from directory
   authorities).

3.5.3.2. Load Balancing Between IPv4 and IPv6 Directories

   We propose this optional change, to improve the load-balancing between IPv4
   and IPv6 directories, when used by relays to find their IPv4 and IPv6
   addresses (see section 3.2.6).

   This change may only be necessary if the following changes result in poor
   load-balancing, or other relay issues:
     * randomly selecting IPv4 or IPv6 directories (see section 3.2.6), or
     * preferring directory header addresses, from directory authorities,
     via an authenticated connection (see sections 3.5.1 and 3.5.2).

   We propose a new torrc option and consensus parameter:
   MaxNumIPv4DirectoryAttempts. This option limits the number of IPv4 directory
   requests, before the relay makes an IPv6 directory request. It should only
   apply to attempts that are expected to provide a usable IPv4 or IPv6
   address in their directory header. (Based on sections 3.2.6, 3.5.1, and
   3.5.2.)

   The design is similar to MaxNumIPv4BootstrapAttempts in
   [Proposal 306: Client Auto IPv6 Connections].

   Here is a quick sketch of the design:
    * when MaxNumIPv4DirectoryAttempts is reached, select an IPv6-capable
      directory, and make an IPv6 connection attempt,
    * use a directory authority, or an ORPort, if required (see sections
      3.5.1 and 3.5.2),
    * use a default value between 2 and 4:
      * the ideal value for load-balancing is >= 2
        (because 6/9 directory authorities are already on IPv6)
      * the ideal value for minimising failures is ~4
        (because relays won't waste too much CPU or bandwidth)
    * choose the default value based on the load-balancing criteria in section
      3.5.3.3.

   Alternately, we could wait until
   [Proposal 306: Client Auto IPv6 Connections] is implemented, and use the
   directory fetch design from that proposal.

3.5.3.3. General Load Balancing Criteria

   We propose the following criteria for choosing load-balancing ratios:

   The selected ratios should be chosen based on the following factors:
     * the current number of directory fetches that a relay makes:
       * when bootstrapping with an empty cache directory, and
       * in a steady state (per hour, or per new consensus),
       (these numbers aren't currently collected by tor, so we may need to
       write some extra code to include them in the heartbeat logs),
     * relays need to discover their IPv4 and IPv6 addresses to publish their
       descriptors,
     * it only takes one successful directory fetch from one authority for a
       relay to discover its IP address (see section 3.5.2),
     * relays will fall back to addresses from directory mirrors, if directory
       authorities are unavailable (see section 3.5.2),
     * BEGINDIR over ORPort requires and TLS connection, and some additional
       tor cryptography, so it is more expensive for authorities than a
       DirPort fetch (and it can not be cached by a HTTP cache)
       (see section 3.5.1),
     * minimising wasted CPU (and bandwidth) for IPv6 connection attempts on
       IPv4-only relays, and
     * other potential changes to relay directory fetches (see
       [Ticket 33018: Dir auths using an unsustainable 400+ mbit/s])

   The selected ratios should allow almost all relays to update both their IPv4
   and IPv6 addresses:
     * at least twice when they bootstrap (to allow for fetch failures),
     * at least once per directory fetch (or per hour), and
     * from a directory authority (if available).

   In this proposal, relays choose between IPv4 and IPv6 directory fetches
   at random (see section 3.2.6 for more detail).

3.5.4. Detailed Address Resolution Logs

   We propose this optional change, to help diagnose relay address resolution
   issues.

   Relays (and bridges) should  log the address chosen using each address
   resolution method, when:
     * address resolution succeeds,
     * address resolution fails,
     * reachability checks fail, or
     * publishing the descriptor fails.
   These logs should be rate-limited separately for successes and failures.

   The logs should tell operators to set the Address torrc option for IPv4 and
   IPv6 (if available).

3.5.5. Add IPv6 Support to is_local_addr()

   We propose this optional change, to improve the accuracy of IPv6 address
   detection from directory documents.

   Directory servers use is_local_addr() to detect if the requesting tor
   instance is on the same local network. If it is, the directory server does
   not include the X-Your-Address-Is HTTP header in directory documents.

   Currently, is_local_addr() checks for:
     * an internal IPv4 or IPv6 address, or
     * the same IPv4 /24 as the directory server.

   We propose also checking for:
     * the same IPv6 /48 as the directory server.

   We choose /48 because it is typically the smallest network in the global
   IPv6 routing tables, and it was previously the recommended per-customer
   network block. (See [RFC 6177: IPv6 End Site Address Assignment].)

   Tor currently uses:
     * IPv4 /8 and IPv6 /16 for port summaries,
     * IPv4 /16 and IPv6 /32 for path selection (avoiding relays in the same
       network block).

3.5.6. Add IPv6 Support to AuthDirMaxServersPerAddr

   We propose this optional change, to improve the health of the network, by
   rejecting too many relays on the same IPv6 address.

   Modify get_possible_sybil_list() so it takes an address family argument,
   and returns a list of IPv4 or IPv6 sybils.

   Use the modified get_possible_sybil_list() to exclude relays from the
   authority's vote, if there are more than AuthDirMaxServersPerAddr on the
   same IPv4 or IPv6 address.

   Since these relay exclusions happen at voting time, they do not require a
   new consensus method.

3.5.7. Use a Local Interface Address on the Default Route

   We propose this optional change, to improve the accuracy of local interface
   IPv4 and IPv6 address detection (see section 3.2.4).

   Rewrite the get_interface_address*() functions to choose an interface
   address on the default route, or to sort default route addresses first in
   the list of addresses. (If the platform API allows us to find the default
   route.)

   For more information, see [Ticket 12377: Prefer default route when checking
   local interface addresses].

   This change might not be necessary, because the directory header IP address
   method will find the IP address of the default route, in most cases
   (see section 3.2.6).

3.5.8. Add IPv6 Support Using gethostbyname2()

   We propose these optional changes, to add IPv6 support to hostname
   resolution on older OSes. These changes affect:
     * the Address torrc option, when it is a hostname (see section 3.2.1),
       and
     * automatic hostname resolution (see section 3.2.5).

   Use gethostbyname2() to add IPv6 support to hostname resolution on older
   OSes, which don't support getaddrinfo().

   But this change may be unnecessary, because:
     * Linux has used getaddrinfo() by default since glibc 2.20 (2014)
     * macOS has recommended getaddrinfo() since before 2006
     * since macOS adopts BSD changes, most BSDs would have switched to
       getaddrinfo() in a similar timeframe
     * Windows has supported getaddrinfo() since Windows Vista; tor's minimum
       supported Windows version is Vista.
   See [Tor Supported Platforms] for more details.

   When looking up hostnames using gethostbyname() or gethostbyname2(), if the
   first address is a private address, we may want to look at the entire list
   of addresses. Some struct hostent versions (example: current macOS) also
   have a h_addr_list rather than h_addr. (They define h_addr as
   h_addr_list[0], for backwards compatibility.)

   However, having private and public addresses resolving from the same
   hostname is a rare configuration, so we might not need to make this change.
   (On OSes that support getaddrinfo(), tor searches the list of addresses for
   a publicly routable address.)

   As an alternative, if we believe that all supported OSes have getaddrinfo(),
   we could simply remove the gethostbyname() code, rather than trying to
   modify it to work with IPv6.

   Most relays can reliably discover their address using directory headers,
   if all other methods fail. Or operators can set the Address torrc option to
   an IPv4 or IPv6 literal.

3.5.9. Change Relay OutboundBindAddress Defaults

   We propose this optional change, to improve the reliability of
   IP address-based filters in tor.

   For example, the tor network treats relay IP addresses differently when:
     * resisting denial of service, and
     * selecting canonical, long-term connections.
   (See [Ticket 33018: Dir auths using an unsustainable 400+ mbit/s] for the
   initial motivation for this change: resisting significant bandwidth load
   on directory authorities.)

   Now that tor knows its own addresses, we propose that relays (and bridges)
   set their IPv4 and IPv6 OutboundBindAddress to these discovered addresses,
   by default. If binding fails, tor should fall back to an unbound socket.

   Operators would still be able to set a custom IPv4 and IPv6
   OutboundBindAddress, if needed.

   Currently, tor doesn't bind to a specific address, unless
   OutboundBindAddress is configured. So on relays with multiple IP addresses,
   the outbound address comes from the chosen route for each TCP connection
   or UDP packet (usually the default route).

3.5.10. IPv6 Address Privacy Extensions

   We propose this optional change, to improve the reliability of relays that
   use IPv6 address privacy extensions (see section 3.5 of
   [RFC 4941: Privacy Extensions for IPv6]).

   We propose that tor should avoid using IPv6 addresses generated using
   privacy extensions, unless no other publicly routable addresses are
   available.

   In practice, each operating system has a different way of detecting IPv6
   address privacy extensions. And some operating systems may not tell
   applications if a particular address is using privacy extensions. So
   implementing this change may be difficult.

   However, even if we do not make this change, tor should be compatible with
   the RFC 4941 defaults:
     * a new IPv6 address is generated each day
     * deprecated addresses are removed after one week
     * temporary addresses should be disabled, unless an application opts in
       to using them
   (See sections 3.5 and  3.6 of [RFC 4941: Privacy Extensions for IPv6].)

   In particular, it can take up to 4.5 hours for a client to receive a new
   address for a relay. Here are the maximum times:
     * 30 minutes for directory authorities to do reachability checks
       (see TestingAuthDirTimeToLearnReachability in the [Tor Manual Page]).
     * 1 hour for a reachable relay to be included in a vote
     * 10 minutes for votes to be turned into a consensus
     * 2 hours and 50 minutes for clients
       (See the [Tor Directory Protocol], sections 1.4 and 5.1, and the
       corresponding Directory Authority options in the [Tor Manual Page].)

   But 4.5 hours is much less than 1 week, and even significantly less than 1
   day. So clients and relays should be compatible with the IPv6 privacy
   extensions defaults, even if they are used for all applications.

   However, bandwidth authorities may reset a relay's bandwidth when its IPv6
   address changes. (The tor network currently uses torflow and sbws as
   bandwidth authorities, neither implementation resets bandwidth when IPv6
   addresses change.) Since bandwidth authorities only scan the whole tor
   network about once a day, resetting a relay's bandwidth causes a huge
   penalty.

   Therefore, we propose that sbws should not reset relay bandwidths when
   IPv6 addresses change. (See
   [Ticket 28725: Reset relay bandwidths when their IPv6 address changes].)

3.5.11. Quick Extends After Relay Restarts

   We propose this optional change, to reduce client circuit failures, after a
   relay restarts.

   We propose that relays (and bridges) should open their ORPorts, and support
   client extends, as soon as possible after they start up. (Clients may
   already have the relay's addresses from a previous consensus.)

   Automatically enabling an IPv6 ORPort creates a race condition with IPv6
   extends (see section 3.2.8 of this proposal, and
   [Proposal 311: Relay IPv6 Reachability]).

   This race condition has the most impact when:
     1. a relay has outbound IPv6 connectivity,
     2. the relay detects a publicly routable IPv6 address,
     3. the relay opens an IPv6 ORPort,
     4. but the IPv6 ORPort is not reachable.

   Between steps 3 and 4, the relay could successfully extend over IPv6, even
   though its IPv6 ORPort is unreachable. However, we expect this case to be
   rare.

   A far more common case is that a working relay has just restarted, and
   clients still have its addresses, therefore they continue to try to extend
   through it. If the relay refused to extend, all these clients would have to
   retry their circuits.

   To support this case, tor relays should open IPv4 and IPv6 ORPorts, and
   perform extends, as soon as they can after startup. Relays can extend to
   other relays, as soon as they have validated the directory documents
   containing other relays' public keys.

   In particular, relays which automatically detect their IPv6 address, should
   support IPv6 extends as soon as they detect an IPv6 address. (Relays may
   also attempt to bind to all IPv6 addresses on all interfaces. If that bind
   is successful, they may choose to extend over IPv6, even before they know
   their own IPv6 address.)

   Relays should not wait for reachable IPv4 or IPv6 ORPorts before they start
   performing client extends.

   DirPort requests are less critical, because relays and clients will retry
   directory fetches using multiple mirrors. However, DirPorts may also open
   as early as possible, for consistency. (And for simpler code.)

   Tor's existing code handles this use case, so the code changes required to
   support IPv6 may be quite small. But we should still test this use case for
   clients connecting over IPv4 and IPv6, and extending over IPv4 and IPv6.

4. Directory Protocol Specification Changes

   We propose explicitly supporting IPv6 X-Your-Address-Is HTTP headers in the
   tor directory protocol.

   We propose the following changes to the [Tor Directory Protocol]
   specification, in section 6.1:

  Servers MAY include an X-Your-Address-Is: header, whose value is the
  apparent IPv4 or IPv6 address of the client connecting to them. IPv6
  addresses SHOULD/MAY (TODO) be formatted enclosed in square brackets.

  TODO: require brackets? What does Tor currently do?

  For directory connections tunneled over a BEGIN_DIR stream, servers SHOULD
  report the IP from which the circuit carrying the BEGIN_DIR stream reached
  them.

  Servers SHOULD disable caching of multiple network statuses or multiple
  server descriptors.  Servers MAY enable caching of single descriptors,
  single network statuses, the list of all server descriptors, a v1
  directory, or a v1 running routers document, with appropriate expiry times
  (around 30 minutes). Servers SHOULD disable caching of X-Your-Address-Is
  headers.

5. Test Plan

   We provide a quick summary of our testing plans.

5.1. Testing Relay IPv6 Addresses Discovery

   We propose to test these changes using chutney networks. However, chutney
   creates a limited number of configurations, so we also need to test these
   changes with relay operators on the public network.

   Therefore, we propose to test these changes on the public network with a
   small number of relays and bridges.

   Once these changes are merged, volunteer relay and bridge operators will be
   able to test them by:
     * compiling from source,
     * running nightly builds, or
     * running alpha releases.

5.2. Test Existing Features

   We will modify and test these existing features:
     * Find Relay IPv4 Addresses

   We do not plan on modifying these existing features:
     * relay address retries
     * existing warning logs
   But we will test that they continue to function correctly, and fix any bugs
   triggered by the modifications in this proposal.

6. Ongoing Monitoring

   To monitor the impact of these changes, relays should collect basic IPv4
   and IPv6 connection and bandwidth statistics (see [Proposal 313: Relay IPv6
   Statistics]).

   We may also collect separate statistics on connections from:
     * clients (and bridges, because they act like clients), and
     * other relays (and authorities, because they act like relays).

   Some of these statistics may be included in tor's heartbeat logs, making
   them accessible to relay operators.

   We do not propose to collect additional statistics on:
     * bridges,
     * address resolution,
     * circuit counts, or
     * failure rates.
   Collecting statistics like these could impact user privacy, or relay
   security.

7. Changes to Other Proposals

   [Proposal 306: Client Auto IPv6 Connections] needs to be modified to keep
   bridge IPv6 behaviour in sync with client IPv6 behaviour. (See section
   3.2.6.)

References:

[getaddrinfo man page]: See the quoted section in:
   https://stackoverflow.com/a/42351676

[Proposal 306: Client Auto IPv6 Connections]: One possible design for
   automatic client IPv4 and IPv6 connections is at
   https://gitweb.torproject.org/torspec.git/tree/proposals/306-ipv6-happy-eyeballs.txt
   (TODO: modify to include bridge changes with client changes)

[Proposal 311: Relay IPv6 Reachability]:
   https://gitweb.torproject.org/torspec.git/tree/proposals/311-relay-ipv6-reachability.txt

[Proposal 313: Relay IPv6 Statistics]:
   https://gitweb.torproject.org/torspec.git/tree/proposals/313-relay-ipv6-stats.txt (TODO)

[RFC 4941: Privacy Extensions for IPv6]:
   https://tools.ietf.org/html/rfc4941
   Or the older RFC 3041: https://tools.ietf.org/html/rfc3041

[RFC 6177: IPv6 End Site Address Assignment]:
   https://tools.ietf.org/html/rfc6177#page-7

[Ticket 12377: Prefer default route when checking local interface addresses]:
   https://trac.torproject.org/projects/tor/ticket/12377

[Ticket 28725: Reset relay bandwidths when their IPv6 address changes]:
   https://trac.torproject.org/projects/tor/ticket/29725#comment:3

[Ticket 33018: Dir auths using an unsustainable 400+ mbit/s]:
   https://trac.torproject.org/projects/tor/ticket/33018

[Tor Directory Protocol]:
   (version 3) https://gitweb.torproject.org/torspec.git/tree/dir-spec.txt

[Tor Manual Page]:
   https://2019.www.torproject.org/docs/tor-manual.html.en

[Tor Specification]:
   https://gitweb.torproject.org/torspec.git/tree/tor-spec.txt

[Tor Supported Platforms]:
   https://trac.torproject.org/projects/tor/wiki/org/teams/NetworkTeam/SupportedPlatforms#OSSupportlevels