12 func newMultiaddr(t *testing.T, a string) Multiaddr {
13 m, err := NewMultiaddr(a)
20 func TestConstructFails(t *testing.T) {
24 "/ip4/fdpsofodsajfdoisa",
28 "/ip6zone//ip6/fe80::1",
35 "/onion/9imaq4ygg2iegci7:80",
36 "/onion/aaimaq4ygg2iegci7:80",
37 "/onion/timaq4ygg2iegci7:0",
38 "/onion/timaq4ygg2iegci7:-1",
39 "/onion/timaq4ygg2iegci7",
40 "/onion/timaq4ygg2iegci@:666",
41 "/onion3/9ww6ybal4bd7szmgncyruucpgfkqahzddi37ktceo3ah7ngmcopnpyyd:80",
42 "/onion3/vww6ybal4bd7szmgncyruucpgfkqahzddi37ktceo3ah7ngmcopnpyyd7:80",
43 "/onion3/vww6ybal4bd7szmgncyruucpgfkqahzddi37ktceo3ah7ngmcopnpyyd:0",
44 "/onion3/vww6ybal4bd7szmgncyruucpgfkqahzddi37ktceo3ah7ngmcopnpyyd:-1",
45 "/onion3/vww6ybal4bd7szmgncyruucpgfkqahzddi37ktceo3ah7ngmcopnpyyd",
46 "/onion3/vww6ybal4bd7szmgncyruucpgfkqahzddi37ktceo3ah7ngmcopnpyy@:666",
47 "/garlic64/jT~IyXaoauTni6N4517EG8mrFUKpy0IlgZh-EY9csMAk82Odatmzr~YTZy8Hv7u~wvkg75EFNOyqb~nAPg-khyp2TS~ObUz8WlqYAM2VlEzJ7wJB91P-cUlKF18zSzVoJFmsrcQHZCirSbWoOknS6iNmsGRh5KVZsBEfp1Dg3gwTipTRIx7Vl5Vy~1OSKQVjYiGZS9q8RL0MF~7xFiKxZDLbPxk0AK9TzGGqm~wMTI2HS0Gm4Ycy8LYPVmLvGonIBYndg2bJC7WLuF6tVjVquiokSVDKFwq70BCUU5AU-EvdOD5KEOAM7mPfw-gJUG4tm1TtvcobrObqoRnmhXPTBTN5H7qDD12AvlwFGnfAlBXjuP4xOUAISL5SRLiulrsMSiT4GcugSI80mF6sdB0zWRgL1yyvoVWeTBn1TqjO27alr95DGTluuSqrNAxgpQzCKEWAyzrQkBfo2avGAmmz2NaHaAvYbOg0QSJz1PLjv2jdPW~ofiQmrGWM1cd~1cCqAAAA7:80",
48 "/garlic64/jT~IyXaoauTni6N4517EG8mrFUKpy0IlgZh-EY9csMAk82Odatmzr~YTZy8Hv7u~wvkg75EFNOyqb~nAPg-khyp2TS~ObUz8WlqYAM2VlEzJ7wJB91P-cUlKF18zSzVoJFmsrcQHZCirSbWoOknS6iNmsGRh5KVZsBEfp1Dg3gwTipTRIx7Vl5Vy~1OSKQVjYiGZS9q8RL0MF~7xFiKxZDLbPxk0AK9TzGGqm~wMTI2HS0Gm4Ycy8LYPVmLvGonIBYndg2bJC7WLuF6tVjVquiokSVDKFwq70BCUU5AU-EvdOD5KEOAM7mPfw-gJUG4tm1TtvcobrObqoRnmhXPTBTN5H7qDD12AvlwFGnfAlBXjuP4xOUAISL5SRLiulrsMSiT4GcugSI80mF6sdB0zWRgL1yyvoVWeTBn1TqjO27alr95DGTluuSqrNAxgpQzCKEWAyzrQkBfo2avGAmmz2NaHaAvYbOg0QSJz1PLjv2jdPW~ofiQmrGWM1cd~1cCqAAAA:0",
49 "/garlic64/jT~IyXaoauTni6N4517EG8mrFUKpy0IlgZh-EY9csMAk82Odatmzr~YTZy8Hv7u~wvkg75EFNOyqb~nAPg-khyp2TS~ObUz8WlqYAM2VlEzJ7wJB91P-cUlKF18zSzVoJFmsrcQHZCirSbWoOknS6iNmsGRh5KVZsBEfp1Dg3gwTipTRIx7Vl5Vy~1OSKQVjYiGZS9q8RL0MF~7xFiKxZDLbPxk0AK9TzGGqm~wMTI2HS0Gm4Ycy8LYPVmLvGonIBYndg2bJC7WLuF6tVjVquiokSVDKFwq70BCUU5AU-EvdOD5KEOAM7mPfw-gJUG4tm1TtvcobrObqoRnmhXPTBTN5H7qDD12AvlwFGnfAlBXjuP4xOUAISL5SRLiulrsMSiT4GcugSI80mF6sdB0zWRgL1yyvoVWeTBn1TqjO27alr95DGTluuSqrNAxgpQzCKEWAyzrQkBfo2avGAmmz2NaHaAvYbOg0QSJz1PLjv2jdPW~ofiQmrGWM1cd~1cCqAAAA:0",
50 "/garlic64/jT~IyXaoauTni6N4517EG8mrFUKpy0IlgZh-EY9csMAk82Odatmzr~YTZy8Hv7u~wvkg75EFNOyqb~nAPg-khyp2TS~ObUz8WlqYAM2VlEzJ7wJB91P-cUlKF18zSzVoJFmsrcQHZCirSbWoOknS6iNmsGRh5KVZsBEfp1Dg3gwTipTRIx7Vl5Vy~1OSKQVjYiGZS9q8RL0MF~7xFiKxZDLbPxk0AK9TzGGqm~wMTI2HS0Gm4Ycy8LYPVmLvGonIBYndg2bJC7WLuF6tVjVquiokSVDKFwq70BCUU5AU-EvdOD5KEOAM7mPfw-gJUG4tm1TtvcobrObqoRnmhXPTBTN5H7qDD12AvlwFGnfAlBXjuP4xOUAISL5SRLiulrsMSiT4GcugSI80mF6sdB0zWRgL1yyvoVWeTBn1TqjO27alr95DGTluuSqrNAxgpQzCKEWAyzrQkBfo2avGAmmz2NaHaAvYbOg0QSJz1PLjv2jdPW~ofiQmrGWM1cd~1cCqAAAA:-1",
51 "/garlic64/jT~IyXaoauTni6N4517EG8mrFUKpy0IlgZh-EY9csMAk82Odatmzr~YTZy8Hv7u~wvkg75EFNOyqb~nAPg-khyp2TS~ObUz8WlqYAM2VlEzJ7wJB91P-cUlKF18zSzVoJFmsrcQHZCirSbWoOknS6iNmsGRh5KVZsBEfp1Dg3gwTipTRIx7Vl5Vy~1OSKQVjYiGZS9q8RL0MF~7xFiKxZDLbPxk0AK9TzGGqm~wMTI2HS0Gm4Ycy8LYPVmLvGonIBYndg2bJC7WLuF6tVjVquiokSVDKFwq70BCUU5AU-EvdOD5KEOAM7mPfw-gJUG4tm1TtvcobrObqoRnmhXPTBTN5H7qDD12AvlwFGnfAlBXjuP4xOUAISL5SRLiulrsMSiT4GcugSI80mF6sdB0zWRgL1yyvoVWeTBn1TqjO27alr95DGTluuSqrNAxgpQzCKEWAyzrQkBfo2avGAmmz2NaHaAvYbOg0QSJz1PLjv2jdPW~ofiQmrGWM1cd~1cCqAAAA@:666",
52 "/garlic64/jT~IyXaoauTni6N4517EG8mrFUKpy0IlgZh-EY9csMAk82Odatmzr~YTZy8Hv7u~wvkg75EFNOyqb~nAPg-khyp2TS~ObUz8WlqYAM2VlEzJ7wJB91P-cUlKF18zSzVoJFmsrcQHZCirSbWoOknS6iNmsGRh5KVZsBEfp1Dg3gwTipTRIx7Vl5Vy~1OSKQVjYiGZS9q8RL0MF~7xFiKxZDLbPxk0AK9TzGGqm~wMTI2HS0Gm4Ycy8LYPVmLvGonIBYndg2bJC7WLuF6tVjVquiokSVDKFwq70BCUU5AU-EvdOD5KEOAM7mPfw-gJUG4tm1TtvcobrObqoRnmhXPTBTN5H7qDD12AvlwFGnfAlBXjuP4xOUAISL5SRLiulrsMSiT4GcugSI80mF6sdB0zWRgL1yyvoVWeTBn1TqjO27alr95DGTluuSqrNAxgpQzCKEWAyzrQkBfo2avGAmmz2NaHaAvYbOg0QSJz1PLjv2jdPW~ofiQmrGWM1cd~1cCqAAAA7:80",
53 "/garlic64/jT~IyXaoauTni6N4517EG8mrFUKpy0IlgZh-EY9csMAk82Odatmzr~YTZy8Hv7u~wvkg75EFNOyqb~nAPg-khyp2TS~ObUz8WlqYAM2VlEzJ7wJB91P-cUlKF18zSzVoJFmsrcQHZCirSbWoOknS6iNmsGRh5KVZsBEfp1Dg3gwTipTRIx7Vl5Vy~1OSKQVjYiGZS9q8RL0MF~7xFiKxZDLbPxk0AK9TzGGqm~wMTI2HS0Gm4Ycy8LYPVmLvGonIBYndg2bJC7WLuF6tVjVquiokSVDKFwq70BCUU5AU-EvdOD5KEOAM7mPfw-gJUG4tm1TtvcobrObqoRnmhXPTBTN5H7qDD12AvlwFGnfAlBXjuP4xOUAISL5SRLiulrsMSiT4GcugSI80mF6sdB0zWRgL1yyvoVWeTBn1TqjO27alr95DGTluuSqrNAxgpQzCKEWAyzrQkBfo2avGAmmz2NaHaAvYbOg0QSJz1PLjv2jdPW~ofiQmrGWM1cd~1cCqAAAA:0",
54 "/garlic64/jT~IyXaoauTni6N4517EG8mrFUKpy0IlgZh-EY9csMAk82Odatmzr~YTZy8Hv7u~wvkg75EFNOyqb~nAPg-khyp2TS~ObUz8WlqYAM2VlEzJ7wJB91P-cUlKF18zSzVoJFmsrcQHZCirSbWoOknS6iNmsGRh5KVZsBEfp1Dg3gwTipTRIx7Vl5Vy~1OSKQVjYiGZS9q8RL0MF~7xFiKxZDLbPxk0AK9TzGGqm~wMTI2HS0Gm4Ycy8LYPVmLvGonIBYndg2bJC7WLuF6tVjVquiokSVDKFwq70BCUU5AU-EvdOD5KEOAM7mPfw-gJUG4tm1TtvcobrObqoRnmhXPTBTN5H7qDD12AvlwFGnfAlBXjuP4xOUAISL5SRLiulrsMSiT4GcugSI80mF6sdB0zWRgL1yyvoVWeTBn1TqjO27alr95DGTluuSqrNAxgpQzCKEWAyzrQkBfo2avGAmmz2NaHaAvYbOg0QSJz1PLjv2jdPW~ofiQmrGWM1cd~1cCqAAAA:0",
55 "/garlic64/jT~IyXaoauTni6N4517EG8mrFUKpy0IlgZh-EY9csMAk82Odatmzr~YTZy8Hv7u~wvkg75EFNOyqb~nAPg-khyp2TS~ObUz8WlqYAM2VlEzJ7wJB91P-cUlKF18zSzVoJFmsrcQHZCirSbWoOknS6iNmsGRh5KVZsBEfp1Dg3gwTipTRIx7Vl5Vy~1OSKQVjYiGZS9q8RL0MF~7xFiKxZDLbPxk0AK9TzGGqm~wMTI2HS0Gm4Ycy8LYPVmLvGonIBYndg2bJC7WLuF6tVjVquiokSVDKFwq70BCUU5AU-EvdOD5KEOAM7mPfw-gJUG4tm1TtvcobrObqoRnmhXPTBTN5H7qDD12AvlwFGnfAlBXjuP4xOUAISL5SRLiulrsMSiT4GcugSI80mF6sdB0zWRgL1yyvoVWeTBn1TqjO27alr95DGTluuSqrNAxgpQzCKEWAyzrQkBfo2avGAmmz2NaHaAvYbOg0QSJz1PLjv2jdPW~ofiQmrGWM1cd~1cCqAAAA:-1",
56 "/garlic64/jT~IyXaoauTni6N4517EG8mrFUKpy0IlgZh-EY9csMAk82Odatmzr~YTZy8Hv7u~wvkg75EFNOyqb~nAPg-khyp2TS~ObUz8WlqYAM2VlEzJ7wJB91P-cUlKF18zSzVoJFmsrcQHZCirSbWoOknS6iNmsGRh5KVZsBEfp1Dg3gwTipTRIx7Vl5Vy~1OSKQVjYiGZS9q8RL0MF~7xFiKxZDLbPxk0AK9TzGGqm~wMTI2HS0Gm4Ycy8LYPVmLvGonIBYndg2bJC7WLuF6tVjVquiokSVDKFwq70BCUU5AU-EvdOD5KEOAM7mPfw-gJUG4tm1TtvcobrObqoRnmhXPTBTN5H7qDD12AvlwFGnfAlBXjuP4xOUAISL5SRLiulrsMSiT4GcugSI80mF6sdB0zWRgL1yyvoVWeTBn1TqjO27alr95DGTluuSqrNAxgpQzCKEWAyzrQkBfo2avGAmmz2NaHaAvYbOg0QSJz1PLjv2jdPW~ofiQmrGWM1cd~1cCqAAAA@:666",
60 "/ip4/127.0.0.1/udp/jfodsajfidosajfoidsa",
62 "/ip4/127.0.0.1/tcp/jfodsajfidosajfoidsa",
64 "/ip4/127.0.0.1/quic/1234",
65 "/ip4/127.0.0.1/ipfs",
66 "/ip4/127.0.0.1/ipfs/tcp",
68 "/ip4/127.0.0.1/p2p/tcp",
70 "/ip4/1.2.3.4/tcp/80/unix",
71 "/ip4/127.0.0.1/tcp/9090/http/p2p-webcrt-direct",
74 for _, a := range cases {
75 if _, err := NewMultiaddr(a); err == nil {
76 t.Errorf("should have failed: %s - %s", a, err)
81 func TestConstructSucceeds(t *testing.T) {
86 "/ip6/2601:9:4f81:9700:803e:ca65:66e8:c21",
87 "/ip6/2601:9:4f81:9700:803e:ca65:66e8:c21/udp/1234/quic",
88 "/ip6zone/x/ip6/fe80::1",
89 "/ip6zone/x%y/ip6/fe80::1",
90 "/ip6zone/x%y/ip6/::",
91 "/ip6zone/x/ip6/fe80::1/udp/1234/quic",
92 "/onion/timaq4ygg2iegci7:1234",
93 "/onion/timaq4ygg2iegci7:80/http",
94 "/onion3/vww6ybal4bd7szmgncyruucpgfkqahzddi37ktceo3ah7ngmcopnpyyd:1234",
95 "/onion3/vww6ybal4bd7szmgncyruucpgfkqahzddi37ktceo3ah7ngmcopnpyyd:80/http",
96 "/garlic64/jT~IyXaoauTni6N4517EG8mrFUKpy0IlgZh-EY9csMAk82Odatmzr~YTZy8Hv7u~wvkg75EFNOyqb~nAPg-khyp2TS~ObUz8WlqYAM2VlEzJ7wJB91P-cUlKF18zSzVoJFmsrcQHZCirSbWoOknS6iNmsGRh5KVZsBEfp1Dg3gwTipTRIx7Vl5Vy~1OSKQVjYiGZS9q8RL0MF~7xFiKxZDLbPxk0AK9TzGGqm~wMTI2HS0Gm4Ycy8LYPVmLvGonIBYndg2bJC7WLuF6tVjVquiokSVDKFwq70BCUU5AU-EvdOD5KEOAM7mPfw-gJUG4tm1TtvcobrObqoRnmhXPTBTN5H7qDD12AvlwFGnfAlBXjuP4xOUAISL5SRLiulrsMSiT4GcugSI80mF6sdB0zWRgL1yyvoVWeTBn1TqjO27alr95DGTluuSqrNAxgpQzCKEWAyzrQkBfo2avGAmmz2NaHaAvYbOg0QSJz1PLjv2jdPW~ofiQmrGWM1cd~1cCqAAAA",
97 "/garlic64/jT~IyXaoauTni6N4517EG8mrFUKpy0IlgZh-EY9csMAk82Odatmzr~YTZy8Hv7u~wvkg75EFNOyqb~nAPg-khyp2TS~ObUz8WlqYAM2VlEzJ7wJB91P-cUlKF18zSzVoJFmsrcQHZCirSbWoOknS6iNmsGRh5KVZsBEfp1Dg3gwTipTRIx7Vl5Vy~1OSKQVjYiGZS9q8RL0MF~7xFiKxZDLbPxk0AK9TzGGqm~wMTI2HS0Gm4Ycy8LYPVmLvGonIBYndg2bJC7WLuF6tVjVquiokSVDKFwq70BCUU5AU-EvdOD5KEOAM7mPfw-gJUG4tm1TtvcobrObqoRnmhXPTBTN5H7qDD12AvlwFGnfAlBXjuP4xOUAISL5SRLiulrsMSiT4GcugSI80mF6sdB0zWRgL1yyvoVWeTBn1TqjO27alr95DGTluuSqrNAxgpQzCKEWAyzrQkBfo2avGAmmz2NaHaAvYbOg0QSJz1PLjv2jdPW~ofiQmrGWM1cd~1cCqAAAA/http",
98 "/garlic64/jT~IyXaoauTni6N4517EG8mrFUKpy0IlgZh-EY9csMAk82Odatmzr~YTZy8Hv7u~wvkg75EFNOyqb~nAPg-khyp2TS~ObUz8WlqYAM2VlEzJ7wJB91P-cUlKF18zSzVoJFmsrcQHZCirSbWoOknS6iNmsGRh5KVZsBEfp1Dg3gwTipTRIx7Vl5Vy~1OSKQVjYiGZS9q8RL0MF~7xFiKxZDLbPxk0AK9TzGGqm~wMTI2HS0Gm4Ycy8LYPVmLvGonIBYndg2bJC7WLuF6tVjVquiokSVDKFwq70BCUU5AU-EvdOD5KEOAM7mPfw-gJUG4tm1TtvcobrObqoRnmhXPTBTN5H7qDD12AvlwFGnfAlBXjuP4xOUAISL5SRLiulrsMSiT4GcugSI80mF6sdB0zWRgL1yyvoVWeTBn1TqjO27alr95DGTluuSqrNAxgpQzCKEWAyzrQkBfo2avGAmmz2NaHaAvYbOg0QSJz1PLjv2jdPW~ofiQmrGWM1cd~1cCqAAAA/udp/8080",
99 "/garlic64/jT~IyXaoauTni6N4517EG8mrFUKpy0IlgZh-EY9csMAk82Odatmzr~YTZy8Hv7u~wvkg75EFNOyqb~nAPg-khyp2TS~ObUz8WlqYAM2VlEzJ7wJB91P-cUlKF18zSzVoJFmsrcQHZCirSbWoOknS6iNmsGRh5KVZsBEfp1Dg3gwTipTRIx7Vl5Vy~1OSKQVjYiGZS9q8RL0MF~7xFiKxZDLbPxk0AK9TzGGqm~wMTI2HS0Gm4Ycy8LYPVmLvGonIBYndg2bJC7WLuF6tVjVquiokSVDKFwq70BCUU5AU-EvdOD5KEOAM7mPfw-gJUG4tm1TtvcobrObqoRnmhXPTBTN5H7qDD12AvlwFGnfAlBXjuP4xOUAISL5SRLiulrsMSiT4GcugSI80mF6sdB0zWRgL1yyvoVWeTBn1TqjO27alr95DGTluuSqrNAxgpQzCKEWAyzrQkBfo2avGAmmz2NaHaAvYbOg0QSJz1PLjv2jdPW~ofiQmrGWM1cd~1cCqAAAA/tcp/8080",
108 "/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC",
109 "/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC",
110 "/udp/1234/sctp/1234",
115 "/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC/tcp/1234",
116 "/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC/tcp/1234",
117 "/ip4/127.0.0.1/udp/1234",
118 "/ip4/127.0.0.1/udp/0",
119 "/ip4/127.0.0.1/tcp/1234",
120 "/ip4/127.0.0.1/tcp/1234/",
121 "/ip4/127.0.0.1/udp/1234/quic",
122 "/ip4/127.0.0.1/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC",
123 "/ip4/127.0.0.1/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC/tcp/1234",
124 "/ip4/127.0.0.1/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC",
125 "/ip4/127.0.0.1/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC/tcp/1234",
128 "/ip4/1.2.3.4/tcp/80/unix/a/b/c/d/e/f",
129 "/ip4/127.0.0.1/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC/tcp/1234/unix/stdio",
130 "/ip4/127.0.0.1/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC/tcp/1234/unix/stdio",
131 "/ip4/127.0.0.1/tcp/9090/http/p2p-webrtc-direct",
134 for _, a := range cases {
135 if _, err := NewMultiaddr(a); err != nil {
136 t.Errorf("should have succeeded: %s -- %s", a, err)
141 func TestEqual(t *testing.T) {
142 m1 := newMultiaddr(t, "/ip4/127.0.0.1/udp/1234")
143 m2 := newMultiaddr(t, "/ip4/127.0.0.1/tcp/1234")
144 m3 := newMultiaddr(t, "/ip4/127.0.0.1/tcp/1234")
145 m4 := newMultiaddr(t, "/ip4/127.0.0.1/tcp/1234/")
148 t.Error("should not be equal")
152 t.Error("should not be equal")
156 t.Error("should be equal")
160 t.Error("should be equal")
164 t.Error("should be equal")
168 t.Error("should be equal")
172 t.Error("should be equal")
176 func TestStringToBytes(t *testing.T) {
178 testString := func(s string, h string) {
179 b1, err := hex.DecodeString(h)
181 t.Error("failed to decode hex", h)
184 b2, err := stringToBytes(s)
186 t.Error("failed to convert", s, err)
189 if !bytes.Equal(b1, b2) {
190 t.Error("failed to convert \n", s, "to\n", b1, "got\n", b2)
193 if err := validateBytes(b2); err != nil {
194 t.Error(err, "len:", len(b2))
198 testString("/ip4/127.0.0.1/udp/1234", "047f000001910204d2")
199 testString("/ip4/127.0.0.1/tcp/4321", "047f0000010610e1")
200 testString("/ip4/127.0.0.1/udp/1234/ip4/127.0.0.1/tcp/4321", "047f000001910204d2047f0000010610e1")
201 testString("/onion/aaimaq4ygg2iegci:80", "bc030010c0439831b48218480050")
202 testString("/onion3/vww6ybal4bd7szmgncyruucpgfkqahzddi37ktceo3ah7ngmcopnpyyd:1234", "bd03adadec040be047f9658668b11a504f3155001f231a37f54c4476c07fb4cc139ed7e30304d2")
203 testString("/garlic64/jT~IyXaoauTni6N4517EG8mrFUKpy0IlgZh-EY9csMAk82Odatmzr~YTZy8Hv7u~wvkg75EFNOyqb~nAPg-khyp2TS~ObUz8WlqYAM2VlEzJ7wJB91P-cUlKF18zSzVoJFmsrcQHZCirSbWoOknS6iNmsGRh5KVZsBEfp1Dg3gwTipTRIx7Vl5Vy~1OSKQVjYiGZS9q8RL0MF~7xFiKxZDLbPxk0AK9TzGGqm~wMTI2HS0Gm4Ycy8LYPVmLvGonIBYndg2bJC7WLuF6tVjVquiokSVDKFwq70BCUU5AU-EvdOD5KEOAM7mPfw-gJUG4tm1TtvcobrObqoRnmhXPTBTN5H7qDD12AvlwFGnfAlBXjuP4xOUAISL5SRLiulrsMSiT4GcugSI80mF6sdB0zWRgL1yyvoVWeTBn1TqjO27alr95DGTluuSqrNAxgpQzCKEWAyzrQkBfo2avGAmmz2NaHaAvYbOg0QSJz1PLjv2jdPW~ofiQmrGWM1cd~1cCqAAAA",
204 "ca0383038d3fc8c976a86ae4e78ba378e75ec41bc9ab1542a9cb422581987e118f5cb0c024f3639d6ad9b3aff613672f07bfbbbfc2f920ef910534ecaa6ff9c03e0fa4872a764d2fce6d4cfc5a5a9800cd95944cc9ef0241f753fe71494a175f334b35682459acadc4076428ab49b5a83a49d2ea2366b06461e4a559b0111fa750e0de0c138a94d1231ed5979572ff53922905636221994bdabc44bd0c17fef11622b16432db3f193400af53cc61aa9bfc0c4c8d874b41a6e18732f0b60f5662ef1a89c80589dd8366c90bb58bb85ead56356aba2a244950ca170abbd01094539014f84bdd383e4a10e00cee63dfc3e809506e2d9b54edbdca1bace6eaa119e68573d30533791fba830f5d80be5c051a77c09415e3b8fe3139400848be5244b8ae96bb0c4a24f819cba0488f34985eac741d3359180bd72cafa1559e4c19f54ea8cedbb6a5afde4319396eb92aab340c60a50cc2284580cb3ad09017e8d9abc60269b3d8d687680bd86ce834412273d4f2e3bf68dd3d6fe87e2426ac658cd5c77fd5c0aa000000")
207 func TestBytesToString(t *testing.T) {
209 testString := func(s1 string, h string) {
211 b, err := hex.DecodeString(h)
213 t.Error("failed to decode hex", h)
216 if err := validateBytes(b); err != nil {
220 s2, err := bytesToString(b)
222 t.Error("failed to convert", b, err)
226 t.Error("failed to convert", b, "to", s1, "got", s2)
230 testString("/ip4/127.0.0.1/udp/1234", "047f000001910204d2")
231 testString("/ip4/127.0.0.1/tcp/4321", "047f0000010610e1")
232 testString("/ip4/127.0.0.1/udp/1234/ip4/127.0.0.1/tcp/4321", "047f000001910204d2047f0000010610e1")
233 testString("/onion/aaimaq4ygg2iegci:80", "bc030010c0439831b48218480050")
234 testString("/onion3/vww6ybal4bd7szmgncyruucpgfkqahzddi37ktceo3ah7ngmcopnpyyd:1234", "bd03adadec040be047f9658668b11a504f3155001f231a37f54c4476c07fb4cc139ed7e30304d2")
235 testString("/garlic64/jT~IyXaoauTni6N4517EG8mrFUKpy0IlgZh-EY9csMAk82Odatmzr~YTZy8Hv7u~wvkg75EFNOyqb~nAPg-khyp2TS~ObUz8WlqYAM2VlEzJ7wJB91P-cUlKF18zSzVoJFmsrcQHZCirSbWoOknS6iNmsGRh5KVZsBEfp1Dg3gwTipTRIx7Vl5Vy~1OSKQVjYiGZS9q8RL0MF~7xFiKxZDLbPxk0AK9TzGGqm~wMTI2HS0Gm4Ycy8LYPVmLvGonIBYndg2bJC7WLuF6tVjVquiokSVDKFwq70BCUU5AU-EvdOD5KEOAM7mPfw-gJUG4tm1TtvcobrObqoRnmhXPTBTN5H7qDD12AvlwFGnfAlBXjuP4xOUAISL5SRLiulrsMSiT4GcugSI80mF6sdB0zWRgL1yyvoVWeTBn1TqjO27alr95DGTluuSqrNAxgpQzCKEWAyzrQkBfo2avGAmmz2NaHaAvYbOg0QSJz1PLjv2jdPW~ofiQmrGWM1cd~1cCqAAAA",
236 "ca0383038d3fc8c976a86ae4e78ba378e75ec41bc9ab1542a9cb422581987e118f5cb0c024f3639d6ad9b3aff613672f07bfbbbfc2f920ef910534ecaa6ff9c03e0fa4872a764d2fce6d4cfc5a5a9800cd95944cc9ef0241f753fe71494a175f334b35682459acadc4076428ab49b5a83a49d2ea2366b06461e4a559b0111fa750e0de0c138a94d1231ed5979572ff53922905636221994bdabc44bd0c17fef11622b16432db3f193400af53cc61aa9bfc0c4c8d874b41a6e18732f0b60f5662ef1a89c80589dd8366c90bb58bb85ead56356aba2a244950ca170abbd01094539014f84bdd383e4a10e00cee63dfc3e809506e2d9b54edbdca1bace6eaa119e68573d30533791fba830f5d80be5c051a77c09415e3b8fe3139400848be5244b8ae96bb0c4a24f819cba0488f34985eac741d3359180bd72cafa1559e4c19f54ea8cedbb6a5afde4319396eb92aab340c60a50cc2284580cb3ad09017e8d9abc60269b3d8d687680bd86ce834412273d4f2e3bf68dd3d6fe87e2426ac658cd5c77fd5c0aa000000")
239 func TestBytesSplitAndJoin(t *testing.T) {
241 testString := func(s string, res []string) {
242 m, err := NewMultiaddr(s)
244 t.Fatal("failed to convert", s, err)
248 if len(split) != len(res) {
249 t.Error("not enough split components", split)
253 for i, a := range split {
254 if a.String() != res[i] {
255 t.Errorf("split component failed: %s != %s", a, res[i])
259 joined := Join(split...)
260 if !m.Equal(joined) {
261 t.Errorf("joined components failed: %s != %s", m, joined)
264 for i, a := range split {
265 if a.String() != res[i] {
266 t.Errorf("split component failed: %s != %s", a, res[i])
271 testString("/ip4/1.2.3.4/udp/1234", []string{"/ip4/1.2.3.4", "/udp/1234"})
272 testString("/ip4/1.2.3.4/tcp/1/ip4/2.3.4.5/udp/2",
273 []string{"/ip4/1.2.3.4", "/tcp/1", "/ip4/2.3.4.5", "/udp/2"})
274 testString("/ip4/1.2.3.4/utp/ip4/2.3.4.5/udp/2/udt",
275 []string{"/ip4/1.2.3.4", "/utp", "/ip4/2.3.4.5", "/udp/2", "/udt"})
278 func TestProtocols(t *testing.T) {
279 m, err := NewMultiaddr("/ip4/127.0.0.1/udp/1234")
281 t.Error("failed to construct", "/ip4/127.0.0.1/udp/1234")
285 if ps[0].Code != ProtocolWithName("ip4").Code {
286 t.Error(ps[0], ProtocolWithName("ip4"))
287 t.Error("failed to get ip4 protocol")
290 if ps[1].Code != ProtocolWithName("udp").Code {
291 t.Error(ps[1], ProtocolWithName("udp"))
292 t.Error("failed to get udp protocol")
297 func TestProtocolsWithString(t *testing.T) {
298 pwn := ProtocolWithName
299 good := map[string][]Protocol{
300 "/ip4": []Protocol{pwn("ip4")},
301 "/ip4/tcp": []Protocol{pwn("ip4"), pwn("tcp")},
302 "ip4/tcp/udp/ip6": []Protocol{pwn("ip4"), pwn("tcp"), pwn("udp"), pwn("ip6")},
303 "////////ip4/tcp": []Protocol{pwn("ip4"), pwn("tcp")},
304 "ip4/udp/////////": []Protocol{pwn("ip4"), pwn("udp")},
305 "////////ip4/tcp////////": []Protocol{pwn("ip4"), pwn("tcp")},
308 for s, ps1 := range good {
309 ps2, err := ProtocolsWithString(s)
311 t.Errorf("ProtocolsWithString(%s) should have succeeded", s)
314 for i, ps1p := range ps1 {
316 if ps1p.Code != ps2p.Code {
317 t.Errorf("mismatch: %s != %s, %s", ps1p.Name, ps2p.Name, s)
323 "dsijafd", // bogus proto
324 "/ip4/tcp/fidosafoidsa", // bogus proto
325 "////////ip4/tcp/21432141/////////", // bogus proto
326 "////////ip4///////tcp/////////", // empty protos in between
329 for _, s := range bad {
330 if _, err := ProtocolsWithString(s); err == nil {
331 t.Errorf("ProtocolsWithString(%s) should have failed", s)
337 func TestEncapsulate(t *testing.T) {
338 m, err := NewMultiaddr("/ip4/127.0.0.1/udp/1234")
343 m2, err := NewMultiaddr("/udp/5678")
348 b := m.Encapsulate(m2)
349 if s := b.String(); s != "/ip4/127.0.0.1/udp/1234/udp/5678" {
350 t.Error("encapsulate /ip4/127.0.0.1/udp/1234/udp/5678 failed.", s)
353 m3, _ := NewMultiaddr("/udp/5678")
354 c := b.Decapsulate(m3)
355 if s := c.String(); s != "/ip4/127.0.0.1/udp/1234" {
356 t.Error("decapsulate /udp failed.", "/ip4/127.0.0.1/udp/1234", s)
359 m4, _ := NewMultiaddr("/ip4/127.0.0.1")
360 d := c.Decapsulate(m4)
361 if s := d.String(); s != "" {
362 t.Error("decapsulate /ip4 failed.", "/", s)
366 func assertValueForProto(t *testing.T, a Multiaddr, p int, exp string) {
367 t.Logf("checking for %s in %s", ProtocolWithCode(p).Name, a)
368 fv, err := a.ValueForProtocol(p)
374 t.Fatalf("expected %q for %d in %s, but got %q instead", exp, p, a, fv)
378 func TestGetValue(t *testing.T) {
379 a := newMultiaddr(t, "/ip4/127.0.0.1/utp/tcp/5555/udp/1234/utp/ipfs/QmbHVEEepCi7rn7VL7Exxpd2Ci9NNB6ifvqwhsrbRMgQFP")
380 assertValueForProto(t, a, P_IP4, "127.0.0.1")
381 assertValueForProto(t, a, P_UTP, "")
382 assertValueForProto(t, a, P_TCP, "5555")
383 assertValueForProto(t, a, P_UDP, "1234")
384 assertValueForProto(t, a, P_IPFS, "QmbHVEEepCi7rn7VL7Exxpd2Ci9NNB6ifvqwhsrbRMgQFP")
385 assertValueForProto(t, a, P_P2P, "QmbHVEEepCi7rn7VL7Exxpd2Ci9NNB6ifvqwhsrbRMgQFP")
387 _, err := a.ValueForProtocol(P_IP6)
389 case ErrProtocolNotFound:
392 t.Fatal("expected value lookup to fail")
394 t.Fatalf("expected ErrProtocolNotFound but got: %s", err)
397 a = newMultiaddr(t, "/ip4/0.0.0.0") // only one addr
398 assertValueForProto(t, a, P_IP4, "0.0.0.0")
400 a = newMultiaddr(t, "/ip4/0.0.0.0/ip4/0.0.0.0/ip4/0.0.0.0") // same sub-addr
401 assertValueForProto(t, a, P_IP4, "0.0.0.0")
403 a = newMultiaddr(t, "/ip4/0.0.0.0/udp/12345/utp") // ending in a no-value one.
404 assertValueForProto(t, a, P_IP4, "0.0.0.0")
405 assertValueForProto(t, a, P_UDP, "12345")
406 assertValueForProto(t, a, P_UTP, "")
408 a = newMultiaddr(t, "/ip4/0.0.0.0/unix/a/b/c/d") // ending in a path one.
409 assertValueForProto(t, a, P_IP4, "0.0.0.0")
410 assertValueForProto(t, a, P_UNIX, "/a/b/c/d")
413 func TestFuzzBytes(t *testing.T) {
414 rand.Seed(time.Now().UnixNano())
415 // Bump up these numbers if you want to stress this
416 buf := make([]byte, 256)
417 for i := 0; i < 2000; i++ {
418 l := rand.Intn(len(buf))
421 // just checking that it doesnt panic
422 ma, err := NewMultiaddrBytes(buf[:l])
424 // for any valid multiaddrs, make sure these calls don't panic
431 func randMaddrString() string {
432 good_corpus := []string{"tcp", "ip", "udp", "ipfs", "0.0.0.0", "127.0.0.1", "12345", "QmbHVEEepCi7rn7VL7Exxpd2Ci9NNB6ifvqwhsrbRMgQFP"}
434 size := rand.Intn(256)
435 parts := make([]string, 0, size)
436 for i := 0; i < size; i++ {
437 switch rand.Intn(5) {
439 parts = append(parts, good_corpus[rand.Intn(len(good_corpus))])
441 badbuf := make([]byte, rand.Intn(256))
443 parts = append(parts, string(badbuf))
447 return "/" + strings.Join(parts, "/")
450 func TestFuzzString(t *testing.T) {
451 rand.Seed(time.Now().UnixNano())
452 // Bump up these numbers if you want to stress this
453 for i := 0; i < 2000; i++ {
455 // just checking that it doesnt panic
456 ma, err := NewMultiaddr(randMaddrString())
458 // for any valid multiaddrs, make sure these calls don't panic
465 func TestBinaryRepresentation(t *testing.T) {
466 expected := []byte{0x4, 0x7f, 0x0, 0x0, 0x1, 0x91, 0x2, 0x4, 0xd2}
467 ma, err := NewMultiaddr("/ip4/127.0.0.1/udp/1234")
472 if !bytes.Equal(ma.Bytes(), expected) {
473 t.Errorf("expected %x, got %x", expected, ma.Bytes())
477 func TestRoundTrip(t *testing.T) {
478 for _, s := range []string{
480 "/ip6/::ffff:127.0.0.1/tcp/111",
481 "/ip4/127.0.0.1/tcp/123",
482 "/ip4/127.0.0.1/udp/123",
483 "/ip4/127.0.0.1/udp/123/ip6/::",
484 "/ipfs/QmbHVEEepCi7rn7VL7Exxpd2Ci9NNB6ifvqwhsrbRMgQFP",
485 "/ipfs/QmbHVEEepCi7rn7VL7Exxpd2Ci9NNB6ifvqwhsrbRMgQFP/unix/a/b/c",
487 ma, err := NewMultiaddr(s)
489 t.Errorf("error when parsing %q: %s", s, err)
492 if ma.String() != s {
493 t.Errorf("failed to round trip %q", s)
498 // XXX: Change this test when we switch to /p2p by default.
499 func TestIPFSvP2P(t *testing.T) {
501 p2pAddr = "/p2p/QmbHVEEepCi7rn7VL7Exxpd2Ci9NNB6ifvqwhsrbRMgQFP"
502 ipfsAddr = "/ipfs/QmbHVEEepCi7rn7VL7Exxpd2Ci9NNB6ifvqwhsrbRMgQFP"
505 for _, s := range []string{p2pAddr, ipfsAddr} {
506 ma, err := NewMultiaddr(s)
508 t.Errorf("error when parsing %q: %s", s, err)
510 if ma.String() != ipfsAddr {
511 t.Errorf("expected %q, got %q", ipfsAddr, ma.String())
516 func TestInvalidP2PAddr(t *testing.T) {
517 badAddr := "a503221221c05877cbae039d70a5e600ea02c6f9f2942439285c9e344e26f8d280c850fad6"
518 bts, err := hex.DecodeString(badAddr)
522 ma, err := NewMultiaddrBytes(bts)
524 t.Error("should have failed")
530 func TestZone(t *testing.T) {
531 ip6String := "/ip6zone/eth0/ip6/::1"
542 ma, err := NewMultiaddr(ip6String)
546 if !bytes.Equal(ma.Bytes(), ip6Bytes) {
547 t.Errorf("expected %x, got %x", ip6Bytes, ma.Bytes())
550 ma2, err2 := NewMultiaddrBytes(ip6Bytes)
554 if ma2.String() != ip6String {
555 t.Errorf("expected %s, got %s", ip6String, ma2.String())