mirror of
https://github.com/syncthing/syncthing.git
synced 2025-12-24 06:28:10 -05:00
Compare commits
595 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1be4b8bb5d | ||
|
|
c832fc9917 | ||
|
|
4797a94689 | ||
|
|
6948903084 | ||
|
|
94164611ae | ||
|
|
ae298e8902 | ||
|
|
3d8771ecb0 | ||
|
|
28db264e90 | ||
|
|
6af9fa4b81 | ||
|
|
60b4d05860 | ||
|
|
7b93839ed1 | ||
|
|
fdb11d7c06 | ||
|
|
5651847877 | ||
|
|
e1442290b6 | ||
|
|
c45b18cc75 | ||
|
|
bb2ad77987 | ||
|
|
68b1ffec19 | ||
|
|
bc2bb22673 | ||
|
|
83d707fc4b | ||
|
|
175b32e56c | ||
|
|
97b4a6553b | ||
|
|
4ade30e681 | ||
|
|
4e03b4f191 | ||
|
|
bfe1d1d4ca | ||
|
|
8918de85fd | ||
|
|
5e237aecae | ||
|
|
13291ad481 | ||
|
|
a47ee86bee | ||
|
|
62d703f967 | ||
|
|
b2c196e5c7 | ||
|
|
4be6a54bc0 | ||
|
|
8ce8476547 | ||
|
|
d82caf6bd4 | ||
|
|
8ea1e302c3 | ||
|
|
a8799efa94 | ||
|
|
0cfac4e021 | ||
|
|
f6c9642d72 | ||
|
|
5a07f9ddee | ||
|
|
9db75e91ac | ||
|
|
f288e00c37 | ||
|
|
c9edd31993 | ||
|
|
5a7780ab5f | ||
|
|
ac0fba99ad | ||
|
|
6f724a113c | ||
|
|
327cd4cb87 | ||
|
|
25de3a2590 | ||
|
|
06208a703a | ||
|
|
56afba6606 | ||
|
|
d65bbf2113 | ||
|
|
b8bfc9b732 | ||
|
|
cec3bad373 | ||
|
|
9312e3c7de | ||
|
|
43e7435c41 | ||
|
|
f34f5e41a4 | ||
|
|
47a70a536b | ||
|
|
bbeddfe522 | ||
|
|
28220310a5 | ||
|
|
3e82a0a259 | ||
|
|
c860ad23a0 | ||
|
|
4e36dd2943 | ||
|
|
13d77f1557 | ||
|
|
cc619f6b53 | ||
|
|
d425794665 | ||
|
|
32da1c8d58 | ||
|
|
830be1035b | ||
|
|
e9e45d0e29 | ||
|
|
d3ca265a25 | ||
|
|
244f0ffaf1 | ||
|
|
73f5c47fe2 | ||
|
|
e8b9600ddb | ||
|
|
d2c813ffac | ||
|
|
8e699f8243 | ||
|
|
3f6cdc829b | ||
|
|
c5c9ee92ac | ||
|
|
7f1fcc9cfc | ||
|
|
9de45c3be4 | ||
|
|
144a881ae5 | ||
|
|
4566690617 | ||
|
|
e8fe1590b6 | ||
|
|
25f4fd5a19 | ||
|
|
7b8c126aa1 | ||
|
|
86b3ff3099 | ||
|
|
fa9df4dc5e | ||
|
|
fbd22e7b94 | ||
|
|
e35411d90f | ||
|
|
be15e48074 | ||
|
|
2be1218aa3 | ||
|
|
c47aebdd2a | ||
|
|
f4d1632506 | ||
|
|
8bfe4374de | ||
|
|
4afe02cb21 | ||
|
|
115b967e5b | ||
|
|
ea4524024a | ||
|
|
4ff6cd9105 | ||
|
|
96c17d8292 | ||
|
|
bc6faaffc4 | ||
|
|
51e9839237 | ||
|
|
6115631746 | ||
|
|
ee005fbc8e | ||
|
|
e27d42935c | ||
|
|
9c99d65716 | ||
|
|
5b9469eed3 | ||
|
|
6805ac915b | ||
|
|
7148cf99f7 | ||
|
|
67a3fb8bf2 | ||
|
|
933b61f99f | ||
|
|
6c5c14f35f | ||
|
|
6a441d5013 | ||
|
|
6b46465c77 | ||
|
|
75388caeed | ||
|
|
2546930a1a | ||
|
|
135e29a3bb | ||
|
|
3b65a58f59 | ||
|
|
49cb931572 | ||
|
|
b7176d2204 | ||
|
|
5bf7d372f6 | ||
|
|
073775e461 | ||
|
|
fbf8f3dc68 | ||
|
|
e8c8cc550b | ||
|
|
87c3790fa8 | ||
|
|
0d9dcb2f4f | ||
|
|
6188185b22 | ||
|
|
f762bd5e25 | ||
|
|
b676264fca | ||
|
|
3640c3b66a | ||
|
|
5087d02fba | ||
|
|
2aa4340551 | ||
|
|
3b34895ae6 | ||
|
|
91cc84c4e6 | ||
|
|
797e53c5ba | ||
|
|
c714a12ad7 | ||
|
|
08ce9b09ec | ||
|
|
3152152ed9 | ||
|
|
544fea51b0 | ||
|
|
08ca9f9378 | ||
|
|
978f68b744 | ||
|
|
680896e4c4 | ||
|
|
975627af2e | ||
|
|
b208102b98 | ||
|
|
88a063434c | ||
|
|
bc0a8fcc1d | ||
|
|
3b4fe19dfb | ||
|
|
58cc108c0c | ||
|
|
d3085a4127 | ||
|
|
0fcc193197 | ||
|
|
75d4d2df8b | ||
|
|
28f2e8f24d | ||
|
|
f692e3ac73 | ||
|
|
bcb5f6f472 | ||
|
|
74fd4a3722 | ||
|
|
884bb638bc | ||
|
|
3388d5b49c | ||
|
|
4fe2992924 | ||
|
|
0a804e39a8 | ||
|
|
f88a7a8e6a | ||
|
|
ec212f73eb | ||
|
|
91cc0cd05e | ||
|
|
7943902d73 | ||
|
|
32a5e83612 | ||
|
|
8b349945de | ||
|
|
fccdd85cc1 | ||
|
|
bd2b5db8f3 | ||
|
|
44bc5fd784 | ||
|
|
45dfd616cb | ||
|
|
39a691a7e6 | ||
|
|
35b5999cba | ||
|
|
d812f559ef | ||
|
|
54a1f37bf5 | ||
|
|
b0f46beffb | ||
|
|
c844991cba | ||
|
|
b7cf8a471f | ||
|
|
864bb8bc34 | ||
|
|
2d4b89a8e9 | ||
|
|
a6d67d30f5 | ||
|
|
0a633c526f | ||
|
|
655acb4cb2 | ||
|
|
91b35118d9 | ||
|
|
c64321df47 | ||
|
|
3f791b57ce | ||
|
|
8de2a7f4c8 | ||
|
|
dbb4b67205 | ||
|
|
f510f5f205 | ||
|
|
620eeae4a7 | ||
|
|
50b37f1366 | ||
|
|
a7b6e35467 | ||
|
|
4cf04a3e0d | ||
|
|
27cd6e60f4 | ||
|
|
2b9fc0fd43 | ||
|
|
d6c058c407 | ||
|
|
8fe5438b59 | ||
|
|
e937e51476 | ||
|
|
b7ea695caf | ||
|
|
31350b4352 | ||
|
|
37d83a4e2e | ||
|
|
4a88d1244d | ||
|
|
439049f672 | ||
|
|
ee10295d04 | ||
|
|
2d272a3cac | ||
|
|
2b26891062 | ||
|
|
3d7d4d845a | ||
|
|
c488179783 | ||
|
|
cfb33321b0 | ||
|
|
193cea95ce | ||
|
|
3c4002e149 | ||
|
|
a720f90a70 | ||
|
|
4a6b43bcae | ||
|
|
2f5a822ca4 | ||
|
|
bc1d04f0b9 | ||
|
|
381795d6d0 | ||
|
|
6ade27641d | ||
|
|
53898d2c60 | ||
|
|
91c4ff6009 | ||
|
|
0aa067a726 | ||
|
|
67445a6dda | ||
|
|
5353659f9f | ||
|
|
7ac00e189b | ||
|
|
071f4c0769 | ||
|
|
b57f4ed97e | ||
|
|
7633b9672f | ||
|
|
4f6ee7c8eb | ||
|
|
d7cc48eab2 | ||
|
|
8f3effed32 | ||
|
|
fee8289c0a | ||
|
|
a2da31056b | ||
|
|
f97dd9d8d3 | ||
|
|
2383579a64 | ||
|
|
68750211ef | ||
|
|
db3e3ade80 | ||
|
|
e6f04ed238 | ||
|
|
a6eb690e31 | ||
|
|
21518adfc8 | ||
|
|
77fe8449ba | ||
|
|
33e9a35f08 | ||
|
|
4ab4816556 | ||
|
|
8e8a579bb2 | ||
|
|
efbdf72d20 | ||
|
|
0e59b5678a | ||
|
|
de75550415 | ||
|
|
4dbce32738 | ||
|
|
b05fcbc9d7 | ||
|
|
d09c71b688 | ||
|
|
874d6760d4 | ||
|
|
26ebbee877 | ||
|
|
12eda0449a | ||
|
|
5a98f4e47c | ||
|
|
964c903a68 | ||
|
|
21b699826d | ||
|
|
5fa8f8e50c | ||
|
|
9ca87f5314 | ||
|
|
537c6b3b69 | ||
|
|
48a3fac2da | ||
|
|
fd73682806 | ||
|
|
34bd5b9dcf | ||
|
|
58c5e46206 | ||
|
|
4c61ab0f18 | ||
|
|
f241b63e0e | ||
|
|
2ffdb5a82a | ||
|
|
46e963443d | ||
|
|
66d4e9e5d7 | ||
|
|
de382e33a3 | ||
|
|
3c6738da73 | ||
|
|
18e5cb6793 | ||
|
|
9cd6b85c09 | ||
|
|
f40f3b3b7b | ||
|
|
7454670b0a | ||
|
|
e63596681d | ||
|
|
3dbaa76dcb | ||
|
|
8752003b50 | ||
|
|
8716ed5aa4 | ||
|
|
38ac4e8f79 | ||
|
|
70fc8a3064 | ||
|
|
7626c5d526 | ||
|
|
7e04c9d048 | ||
|
|
9eda8f2c7e | ||
|
|
456d9e870d | ||
|
|
a1533696a5 | ||
|
|
92499af323 | ||
|
|
b2988cdd35 | ||
|
|
82cfd37263 | ||
|
|
df381fd03f | ||
|
|
5a2328d9a5 | ||
|
|
b2f66cfb60 | ||
|
|
6d24e4f122 | ||
|
|
2e2185165c | ||
|
|
f0612e57c2 | ||
|
|
e5d16ed08a | ||
|
|
1cff9ccc63 | ||
|
|
20a018db2e | ||
|
|
80c2b32b92 | ||
|
|
028e9bc17a | ||
|
|
afc2d6fda4 | ||
|
|
bec5c76631 | ||
|
|
d87051ca99 | ||
|
|
3798cebad0 | ||
|
|
a477989950 | ||
|
|
5065d1d0b4 | ||
|
|
829990c9ef | ||
|
|
ac037e0fa3 | ||
|
|
da42d51008 | ||
|
|
99027813ef | ||
|
|
9112ba8f0b | ||
|
|
843fd9bdbd | ||
|
|
26c33c4a69 | ||
|
|
2db76ae786 | ||
|
|
a0b15d006d | ||
|
|
23b27fa24a | ||
|
|
b6f580cbc2 | ||
|
|
f2459ef331 | ||
|
|
0a37fac794 | ||
|
|
2d9a822ed7 | ||
|
|
98622ca4d0 | ||
|
|
f7a25adcbd | ||
|
|
9bf13b253c | ||
|
|
2e8b639a34 | ||
|
|
672f7a010f | ||
|
|
37e15c4368 | ||
|
|
4d7837ba96 | ||
|
|
a6c8423905 | ||
|
|
832ed556d9 | ||
|
|
7c6fb018ca | ||
|
|
9c5c06bf31 | ||
|
|
61e3daaead | ||
|
|
9c0fde795e | ||
|
|
ce4f565e2f | ||
|
|
5369a62fd5 | ||
|
|
b44016ff70 | ||
|
|
9f76c87880 | ||
|
|
42ae2898e1 | ||
|
|
dd649a6be4 | ||
|
|
593f098276 | ||
|
|
4a87221f16 | ||
|
|
7745ed34d3 | ||
|
|
8fe546c4a2 | ||
|
|
381f6aeaf6 | ||
|
|
9154bacced | ||
|
|
dc0dc8efb4 | ||
|
|
b062d5dd7f | ||
|
|
c519e582b5 | ||
|
|
6b9dce36bf | ||
|
|
8e0520887a | ||
|
|
cfd1fdb38e | ||
|
|
c6ba0208d0 | ||
|
|
3d055bbb79 | ||
|
|
dd971b56e5 | ||
|
|
4031f5e24b | ||
|
|
1cd7cc6869 | ||
|
|
9de2864db3 | ||
|
|
c27861cbaf | ||
|
|
c2f75d3689 | ||
|
|
5454ca1cf7 | ||
|
|
8644bf30a9 | ||
|
|
db3341a178 | ||
|
|
e2cb0219c7 | ||
|
|
217f29de76 | ||
|
|
8661afcb4f | ||
|
|
ed07fc0f2c | ||
|
|
4af3f77a9a | ||
|
|
8c4f07ef1b | ||
|
|
1a231d39a5 | ||
|
|
17e3d14272 | ||
|
|
03182c7714 | ||
|
|
963078f6ac | ||
|
|
8356b58b1d | ||
|
|
303ce02271 | ||
|
|
bcdc3ecdae | ||
|
|
b60d648e22 | ||
|
|
7bc36cbbd1 | ||
|
|
04130fcb15 | ||
|
|
52d8e4c691 | ||
|
|
ae0193b724 | ||
|
|
2e1c33206f | ||
|
|
0c642ec7cf | ||
|
|
b3ca96eeba | ||
|
|
ae0e033178 | ||
|
|
a97985b428 | ||
|
|
63c0f11458 | ||
|
|
5b0dd9d3b2 | ||
|
|
8bba82a08d | ||
|
|
51bf15728a | ||
|
|
b336b2c336 | ||
|
|
2331089854 | ||
|
|
8a5a573851 | ||
|
|
6fb05fc82a | ||
|
|
358862c7ad | ||
|
|
4235175966 | ||
|
|
cd433a4f52 | ||
|
|
f3b550744f | ||
|
|
f31e5eaba2 | ||
|
|
7c8652b600 | ||
|
|
30837a7d95 | ||
|
|
3c25a74f3b | ||
|
|
da3177dbe0 | ||
|
|
3ca8dce98b | ||
|
|
e17fa7b14e | ||
|
|
230f149b4b | ||
|
|
dd3d8a6c98 | ||
|
|
36bdd9cb4d | ||
|
|
95f5e5fa9a | ||
|
|
1aef03288a | ||
|
|
a8c510cc72 | ||
|
|
e359b146aa | ||
|
|
dba40eefb1 | ||
|
|
23b55f68b7 | ||
|
|
5c65e10875 | ||
|
|
d7df11e724 | ||
|
|
c08ce5c571 | ||
|
|
12a6682eaf | ||
|
|
bbefcef53b | ||
|
|
729b0143e1 | ||
|
|
84c4298cd5 | ||
|
|
7d672fd989 | ||
|
|
1442d6f4c2 | ||
|
|
13022817d4 | ||
|
|
e788a99c3e | ||
|
|
09d4b3f71e | ||
|
|
78f0f2b131 | ||
|
|
40c750141a | ||
|
|
b60251b960 | ||
|
|
958c39ef5f | ||
|
|
e22ddae3a8 | ||
|
|
68afc897d6 | ||
|
|
ba58e95f6b | ||
|
|
adbd0b1834 | ||
|
|
3e34fc66e6 | ||
|
|
f8e34c083e | ||
|
|
cba554d0fa | ||
|
|
8903825e02 | ||
|
|
81cd84add2 | ||
|
|
8229d47da5 | ||
|
|
8f14d11d66 | ||
|
|
76f82cbd1f | ||
|
|
dc2f83e522 | ||
|
|
8b4282fe28 | ||
|
|
c6416b235b | ||
|
|
79f2b3bd7e | ||
|
|
1f996afa21 | ||
|
|
21335d65c4 | ||
|
|
870ce57005 | ||
|
|
0d3caa2183 | ||
|
|
602d7e8d18 | ||
|
|
a2309f3119 | ||
|
|
9a51be8548 | ||
|
|
5ed319ea42 | ||
|
|
eb7a70a3c9 | ||
|
|
b61f418bf2 | ||
|
|
1338b0a2f8 | ||
|
|
587e1a4f4c | ||
|
|
85d5449b3c | ||
|
|
532b576fd5 | ||
|
|
dd1197236d | ||
|
|
e8a9abaf40 | ||
|
|
1bf07d6b58 | ||
|
|
30ea9cb37e | ||
|
|
bae9247d84 | ||
|
|
a105ad1391 | ||
|
|
abbb40abd2 | ||
|
|
20b23338f7 | ||
|
|
0fcbee6478 | ||
|
|
1d602b9efa | ||
|
|
b783169c72 | ||
|
|
e4f266883a | ||
|
|
7a41362d90 | ||
|
|
3ed783983f | ||
|
|
837f3a68ab | ||
|
|
59e45c5c68 | ||
|
|
94761d0472 | ||
|
|
a91eb701bf | ||
|
|
1a1f118f1a | ||
|
|
b115fca8a9 | ||
|
|
dfd239ac06 | ||
|
|
2ae218d069 | ||
|
|
1401d2ee9b | ||
|
|
f39e105101 | ||
|
|
482795bab0 | ||
|
|
10e8861f14 | ||
|
|
ecc6476308 | ||
|
|
28e347002a | ||
|
|
b3d19bd5cc | ||
|
|
647165ab89 | ||
|
|
6807d9bd4c | ||
|
|
699ecc7140 | ||
|
|
b374ec9355 | ||
|
|
9659d021cb | ||
|
|
a4ad9eb134 | ||
|
|
a455258a62 | ||
|
|
0ae342673a | ||
|
|
33d75a264d | ||
|
|
89dc5bb951 | ||
|
|
45403917de | ||
|
|
ed476271a6 | ||
|
|
1e92c47960 | ||
|
|
4f2fe07ae4 | ||
|
|
aff3cd01c5 | ||
|
|
ac74ee1468 | ||
|
|
0d55cf4be5 | ||
|
|
5399a25532 | ||
|
|
ae882c93c9 | ||
|
|
f398ca77c1 | ||
|
|
dcd7d278aa | ||
|
|
89f5f3bf9a | ||
|
|
76ef42ee07 | ||
|
|
92c1ce57a6 | ||
|
|
116f232f5a | ||
|
|
ef81a36654 | ||
|
|
9fd2724d73 | ||
|
|
07d49b61d0 | ||
|
|
0c4e6ae7de | ||
|
|
65ec129dfb | ||
|
|
3e4d628f54 | ||
|
|
71684bfa45 | ||
|
|
e73b7e0398 | ||
|
|
35ebdc76ff | ||
|
|
90d0896848 | ||
|
|
5528db9693 | ||
|
|
aa78fbb09d | ||
|
|
d53b193e09 | ||
|
|
e0e16c371f | ||
|
|
53cd877899 | ||
|
|
1207223f3d | ||
|
|
39be6932b5 | ||
|
|
44a194d226 | ||
|
|
9349eb77cd | ||
|
|
c64549471a | ||
|
|
264bcbc78c | ||
|
|
f76fe1ac7a | ||
|
|
6364c4ff3f | ||
|
|
292a50de04 | ||
|
|
a08cba9c85 | ||
|
|
9fb60d6935 | ||
|
|
f2ed2d98d8 | ||
|
|
b802cb1e36 | ||
|
|
31bfd8c039 | ||
|
|
f72ee7a69e | ||
|
|
a98d75edaa | ||
|
|
622568c327 | ||
|
|
1ca7e47fd6 | ||
|
|
116203aef8 | ||
|
|
1bf128612d | ||
|
|
935a8eb9a7 | ||
|
|
7e5b350096 | ||
|
|
5c75869e85 | ||
|
|
fbd5ddea72 | ||
|
|
bc8e033eb5 | ||
|
|
70fa5ffa06 | ||
|
|
fb162ff529 | ||
|
|
9d535b13cf | ||
|
|
48bfc2d9ed | ||
|
|
5064f846fc | ||
|
|
41c228cb56 | ||
|
|
e974c8f33e | ||
|
|
94f5d5b59e | ||
|
|
433a0cb9cc | ||
|
|
c42a6b511c | ||
|
|
346b6f4f11 | ||
|
|
07eb4020bd | ||
|
|
c2f0c2225a | ||
|
|
711587492c | ||
|
|
536613f008 | ||
|
|
c832fc7d1b | ||
|
|
0b654581b6 | ||
|
|
cbae64fc06 | ||
|
|
1443a1388e | ||
|
|
a203d99182 | ||
|
|
bc5ff6e1b6 | ||
|
|
3b3c0c5950 | ||
|
|
ee0ee0e39d | ||
|
|
8dee10ba9c | ||
|
|
d3915b8dbf | ||
|
|
671d5cace6 | ||
|
|
aa3d73d322 | ||
|
|
d30a286f38 | ||
|
|
15699a39cf | ||
|
|
a1f32095df | ||
|
|
76e0960a51 | ||
|
|
8e33288156 | ||
|
|
f4d3a9980f | ||
|
|
fc8ce7c6e0 | ||
|
|
aaf0604601 | ||
|
|
dddf563105 | ||
|
|
dbe12cca4b | ||
|
|
ddf0ddbd05 | ||
|
|
5eb5a056bf | ||
|
|
2a5c0646c0 | ||
|
|
7d3c51df9e | ||
|
|
a67bb5e720 | ||
|
|
6d314cdc04 | ||
|
|
1139ea2c81 | ||
|
|
f87b1520e8 | ||
|
|
3700eb1e61 | ||
|
|
17a21102b3 | ||
|
|
e37441627f | ||
|
|
f4c6cd1676 | ||
|
|
bcd3fd40e4 | ||
|
|
d3d1a79996 | ||
|
|
fb4a2c9b5a |
6
.gitignore
vendored
6
.gitignore
vendored
@@ -3,3 +3,9 @@ syncthing.exe
|
||||
*.tar.gz
|
||||
*.zip
|
||||
*.asc
|
||||
*.sublime*
|
||||
.jshintrc
|
||||
coverage.out
|
||||
files/pidx
|
||||
bin
|
||||
perfstats*.csv
|
||||
|
||||
18
.travis.yml
Normal file
18
.travis.yml
Normal file
@@ -0,0 +1,18 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- tip
|
||||
|
||||
install:
|
||||
- export PATH=$PATH:$HOME/gopath/bin
|
||||
- ./build.sh setup
|
||||
|
||||
script:
|
||||
- ./build.sh test-cov
|
||||
|
||||
after_success:
|
||||
- goveralls -coverprofile=coverage.out -service=travis-ci -package=syncthing/syncthing -repotoken="$COVERALLS_TOKEN"
|
||||
|
||||
env:
|
||||
global:
|
||||
secure: "TSPJDsokGCQhKLjgG3c58qHn8Qxhh4zEkWFf0XIOOY2nlDVzdgXDsC+Nq0YaP4106Ee4FgkSefsUTQV5lq/IyYW8elgqlgghjOtOi6RJa14eIS9Yy5Bkx6MXn0QfZX/lG+sy42pKSNk43y9GWx/qrt4nkfTtTvI5cXgwDGYdmX8="
|
||||
@@ -1,8 +1,75 @@
|
||||
Please do contribute!
|
||||
## Reporting Bugs
|
||||
|
||||
Please file bugs in the [Github Issue
|
||||
Tracker](https://github.com/syncthing/syncthing/issues). Include at
|
||||
least the following:
|
||||
|
||||
- What happened
|
||||
|
||||
- What did you expect to happen instead of what *did* happen, if it's
|
||||
not crazy obvious
|
||||
|
||||
- What operating system, operating system version and version of
|
||||
Syncthing you are running
|
||||
|
||||
- The same for other connected nodes, where relevant
|
||||
|
||||
- Screenshot if the issue concerns something visible in the GUI
|
||||
|
||||
- Console log entries, where possible and relevant
|
||||
|
||||
If you're not sure whether something is relevant, erring on the side of
|
||||
too much information will never get you yelled at. :)
|
||||
|
||||
## Contributing Translations
|
||||
|
||||
All translations are done via
|
||||
[Transifex](https://www.transifex.com/projects/p/syncthing/). If you
|
||||
wish to contribute to a translation, just head over there and sign up.
|
||||
Before every release, the language resources are updated from the
|
||||
latest info on Transifex.
|
||||
|
||||
## Contributing Code
|
||||
|
||||
Please do contribute! If you want to contribute but are unsure where to
|
||||
start, the [Contributions Needed
|
||||
topic](http://discourse.syncthing.net/t/49) lists areas in need of
|
||||
attention. In general, any open issues are fair game!
|
||||
|
||||
## Licensing
|
||||
|
||||
All contributions are made under the same MIT License as the rest of the
|
||||
project, except documentation which is licensed under the Creative
|
||||
Commons Attribution 4.0 International License. You retain the copyright
|
||||
to code you have written.
|
||||
|
||||
When accepting your first contribution, the maintainer of the project
|
||||
will ensure that you are added to the CONTRIBUTORS file. You are welcome
|
||||
to add yourself as a separate commit in your first pull request.
|
||||
|
||||
## Building
|
||||
|
||||
[See the wiki](https://github.com/calmh/syncthing/wiki/Building)
|
||||
[See the documentation](http://discourse.syncthing.net/t/44) on how to
|
||||
get started with a build environment.
|
||||
|
||||
## Branches
|
||||
|
||||
- `master` is the main branch containing good code that will end up in
|
||||
the next release. You should base your work on it. It won't ever be
|
||||
rebased or force-pushed to.
|
||||
|
||||
- `vx.y` branches exist to make patch releases on otherwise obsolete
|
||||
minor releases. Should only contain fixes cherry picked from master.
|
||||
Don't base any work on them.
|
||||
|
||||
- Other branches are probably topic branches and may be subject to
|
||||
rebasing. Don't base any work on them unless you specifically know
|
||||
otherwise.
|
||||
|
||||
## Tags
|
||||
|
||||
All releases are tagged semver style as `vx.y.z`. Release tags are
|
||||
signed by GPG key BCE524C7.
|
||||
|
||||
## Tests
|
||||
|
||||
@@ -10,13 +77,14 @@ Yes please!
|
||||
|
||||
## Style
|
||||
|
||||
`go fmt`
|
||||
- `go fmt`
|
||||
|
||||
- Unix line breaks
|
||||
|
||||
## Documentation
|
||||
|
||||
[Hack it here](https://github.com/calmh/syncthing/wiki)
|
||||
[Over here!](http://discourse.syncthing.net/category/documentation)
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
|
||||
13
CONTRIBUTORS
Normal file
13
CONTRIBUTORS
Normal file
@@ -0,0 +1,13 @@
|
||||
Aaron Bieber <qbit@deftly.net>
|
||||
Andrew Dunham <andrew@du.nham.ca>
|
||||
Audrius Butkevicius <audrius.butkevicius@gmail.com>
|
||||
Arthur Axel fREW Schmidt <frew@afoolishmanifesto.com>
|
||||
Ben Sidhom <bsidhom@gmail.com>
|
||||
Brandon Philips <brandon@ifup.org>
|
||||
Gilli Sigurdsson <gilli@vx.is>
|
||||
James Patterson <jamespatterson@operamail.com>
|
||||
Jens Diemer <github.com@jensdiemer.de>
|
||||
Philippe Schommers <philippe@schommers.be>
|
||||
Ryan Sullivan <kayoticsully@gmail.com>
|
||||
Tully Robinson <tully@tojr.org>
|
||||
Veeti Paananen <veeti.paananen@rojekti.fi>
|
||||
64
Godeps/Godeps.json
generated
64
Godeps/Godeps.json
generated
@@ -1,37 +1,67 @@
|
||||
{
|
||||
"ImportPath": "github.com/calmh/syncthing",
|
||||
"GoVersion": "devel +3ca54dd30864 Sat Mar 22 11:05:40 2014 -0700",
|
||||
"ImportPath": "github.com/syncthing/syncthing",
|
||||
"GoVersion": "go1.3",
|
||||
"Packages": [
|
||||
"./cmd/syncthing"
|
||||
"./cmd/..."
|
||||
],
|
||||
"Deps": [
|
||||
{
|
||||
"ImportPath": "code.google.com/p/go.net/ipv6",
|
||||
"Comment": "null-117",
|
||||
"Rev": "c17ad62118ea511e1051721b429779fa40bddc74"
|
||||
"ImportPath": "bitbucket.org/kardianos/osext",
|
||||
"Comment": "null-13",
|
||||
"Rev": "5d3ddcf53a508cc2f7404eaebf546ef2cb5cdb6e"
|
||||
},
|
||||
{
|
||||
"ImportPath": "code.google.com/p/go.crypto/bcrypt",
|
||||
"Comment": "null-213",
|
||||
"Rev": "aa2644fe4aa50e3b38d75187b4799b1f0c9ddcef"
|
||||
},
|
||||
{
|
||||
"ImportPath": "code.google.com/p/go.crypto/blowfish",
|
||||
"Comment": "null-213",
|
||||
"Rev": "aa2644fe4aa50e3b38d75187b4799b1f0c9ddcef"
|
||||
},
|
||||
{
|
||||
"ImportPath": "code.google.com/p/go.text/transform",
|
||||
"Comment": "null-81",
|
||||
"Rev": "9cbe983aed9b0dfc73954433fead5e00866342ac"
|
||||
"Comment": "null-89",
|
||||
"Rev": "df15baaf13e3f62b6b7a901e74caa3818a7c0a7c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "code.google.com/p/go.text/unicode/norm",
|
||||
"Comment": "null-81",
|
||||
"Rev": "9cbe983aed9b0dfc73954433fead5e00866342ac"
|
||||
"Comment": "null-89",
|
||||
"Rev": "df15baaf13e3f62b6b7a901e74caa3818a7c0a7c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/calmh/ini",
|
||||
"Rev": "386c4240a9684d91d9ec4d93651909b49c7269e1"
|
||||
"ImportPath": "code.google.com/p/snappy-go/snappy",
|
||||
"Comment": "null-15",
|
||||
"Rev": "12e4b4183793ac4b061921e7980845e750679fd0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/codegangsta/inject",
|
||||
"Rev": "9aea7a2fa5b79ef7fc00f63a575e72df33b4e886"
|
||||
"ImportPath": "github.com/bkaradzic/go-lz4",
|
||||
"Rev": "77e2ba877bde9da31213bec75dbbe197fa507c21"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/codegangsta/martini",
|
||||
"Comment": "v0.1-142-g8659df7",
|
||||
"Rev": "8659df7a51aebe6c6120268cd5a8b4c34fa8441a"
|
||||
"ImportPath": "github.com/calmh/xdr",
|
||||
"Rev": "694859acb207675085232438780db923ceb43e96"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/juju/ratelimit",
|
||||
"Rev": "f9f36d11773655c0485207f0ad30dc2655f69d56"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/syndtr/goleveldb/leveldb",
|
||||
"Rev": "c5955912e3287376475731c5bc59c79a5a799105"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vitrun/qart/coding",
|
||||
"Rev": "ccb109cf25f0cd24474da73b9fee4e7a3e8a8ce0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vitrun/qart/gf256",
|
||||
"Rev": "ccb109cf25f0cd24474da73b9fee4e7a3e8a8ce0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vitrun/qart/qr",
|
||||
"Rev": "ccb109cf25f0cd24474da73b9fee4e7a3e8a8ce0"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
20
Godeps/_workspace/src/bitbucket.org/kardianos/osext/LICENSE
generated
vendored
Normal file
20
Godeps/_workspace/src/bitbucket.org/kardianos/osext/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
Copyright (c) 2012 Daniel Theophanes
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
32
Godeps/_workspace/src/bitbucket.org/kardianos/osext/osext.go
generated
vendored
Normal file
32
Godeps/_workspace/src/bitbucket.org/kardianos/osext/osext.go
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Extensions to the standard "os" package.
|
||||
package osext
|
||||
|
||||
import "path/filepath"
|
||||
|
||||
// Executable returns an absolute path that can be used to
|
||||
// re-invoke the current program.
|
||||
// It may not be valid after the current program exits.
|
||||
func Executable() (string, error) {
|
||||
p, err := executable()
|
||||
return filepath.Clean(p), err
|
||||
}
|
||||
|
||||
// Returns same path as Executable, returns just the folder
|
||||
// path. Excludes the executable name.
|
||||
func ExecutableFolder() (string, error) {
|
||||
p, err := Executable()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
folder, _ := filepath.Split(p)
|
||||
return folder, nil
|
||||
}
|
||||
|
||||
// Depricated. Same as Executable().
|
||||
func GetExePath() (exePath string, err error) {
|
||||
return Executable()
|
||||
}
|
||||
20
Godeps/_workspace/src/bitbucket.org/kardianos/osext/osext_plan9.go
generated
vendored
Normal file
20
Godeps/_workspace/src/bitbucket.org/kardianos/osext/osext_plan9.go
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package osext
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func executable() (string, error) {
|
||||
f, err := os.Open("/proc/" + strconv.Itoa(os.Getpid()) + "/text")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer f.Close()
|
||||
return syscall.Fd2path(int(f.Fd()))
|
||||
}
|
||||
25
Godeps/_workspace/src/bitbucket.org/kardianos/osext/osext_procfs.go
generated
vendored
Normal file
25
Godeps/_workspace/src/bitbucket.org/kardianos/osext/osext_procfs.go
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build linux netbsd openbsd
|
||||
|
||||
package osext
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
func executable() (string, error) {
|
||||
switch runtime.GOOS {
|
||||
case "linux":
|
||||
return os.Readlink("/proc/self/exe")
|
||||
case "netbsd":
|
||||
return os.Readlink("/proc/curproc/exe")
|
||||
case "openbsd":
|
||||
return os.Readlink("/proc/curproc/file")
|
||||
}
|
||||
return "", errors.New("ExecPath not implemented for " + runtime.GOOS)
|
||||
}
|
||||
79
Godeps/_workspace/src/bitbucket.org/kardianos/osext/osext_sysctl.go
generated
vendored
Normal file
79
Godeps/_workspace/src/bitbucket.org/kardianos/osext/osext_sysctl.go
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build darwin freebsd
|
||||
|
||||
package osext
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var initCwd, initCwdErr = os.Getwd()
|
||||
|
||||
func executable() (string, error) {
|
||||
var mib [4]int32
|
||||
switch runtime.GOOS {
|
||||
case "freebsd":
|
||||
mib = [4]int32{1 /* CTL_KERN */, 14 /* KERN_PROC */, 12 /* KERN_PROC_PATHNAME */, -1}
|
||||
case "darwin":
|
||||
mib = [4]int32{1 /* CTL_KERN */, 38 /* KERN_PROCARGS */, int32(os.Getpid()), -1}
|
||||
}
|
||||
|
||||
n := uintptr(0)
|
||||
// Get length.
|
||||
_, _, errNum := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 4, 0, uintptr(unsafe.Pointer(&n)), 0, 0)
|
||||
if errNum != 0 {
|
||||
return "", errNum
|
||||
}
|
||||
if n == 0 { // This shouldn't happen.
|
||||
return "", nil
|
||||
}
|
||||
buf := make([]byte, n)
|
||||
_, _, errNum = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 4, uintptr(unsafe.Pointer(&buf[0])), uintptr(unsafe.Pointer(&n)), 0, 0)
|
||||
if errNum != 0 {
|
||||
return "", errNum
|
||||
}
|
||||
if n == 0 { // This shouldn't happen.
|
||||
return "", nil
|
||||
}
|
||||
for i, v := range buf {
|
||||
if v == 0 {
|
||||
buf = buf[:i]
|
||||
break
|
||||
}
|
||||
}
|
||||
var err error
|
||||
execPath := string(buf)
|
||||
// execPath will not be empty due to above checks.
|
||||
// Try to get the absolute path if the execPath is not rooted.
|
||||
if execPath[0] != '/' {
|
||||
execPath, err = getAbs(execPath)
|
||||
if err != nil {
|
||||
return execPath, err
|
||||
}
|
||||
}
|
||||
// For darwin KERN_PROCARGS may return the path to a symlink rather than the
|
||||
// actual executable.
|
||||
if runtime.GOOS == "darwin" {
|
||||
if execPath, err = filepath.EvalSymlinks(execPath); err != nil {
|
||||
return execPath, err
|
||||
}
|
||||
}
|
||||
return execPath, nil
|
||||
}
|
||||
|
||||
func getAbs(execPath string) (string, error) {
|
||||
if initCwdErr != nil {
|
||||
return execPath, initCwdErr
|
||||
}
|
||||
// The execPath may begin with a "../" or a "./" so clean it first.
|
||||
// Join the two paths, trailing and starting slashes undetermined, so use
|
||||
// the generic Join function.
|
||||
return filepath.Join(initCwd, filepath.Clean(execPath)), nil
|
||||
}
|
||||
79
Godeps/_workspace/src/bitbucket.org/kardianos/osext/osext_test.go
generated
vendored
Normal file
79
Godeps/_workspace/src/bitbucket.org/kardianos/osext/osext_test.go
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build darwin linux freebsd netbsd windows
|
||||
|
||||
package osext
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
oexec "os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const execPath_EnvVar = "OSTEST_OUTPUT_EXECPATH"
|
||||
|
||||
func TestExecPath(t *testing.T) {
|
||||
ep, err := Executable()
|
||||
if err != nil {
|
||||
t.Fatalf("ExecPath failed: %v", err)
|
||||
}
|
||||
// we want fn to be of the form "dir/prog"
|
||||
dir := filepath.Dir(filepath.Dir(ep))
|
||||
fn, err := filepath.Rel(dir, ep)
|
||||
if err != nil {
|
||||
t.Fatalf("filepath.Rel: %v", err)
|
||||
}
|
||||
cmd := &oexec.Cmd{}
|
||||
// make child start with a relative program path
|
||||
cmd.Dir = dir
|
||||
cmd.Path = fn
|
||||
// forge argv[0] for child, so that we can verify we could correctly
|
||||
// get real path of the executable without influenced by argv[0].
|
||||
cmd.Args = []string{"-", "-test.run=XXXX"}
|
||||
cmd.Env = []string{fmt.Sprintf("%s=1", execPath_EnvVar)}
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
t.Fatalf("exec(self) failed: %v", err)
|
||||
}
|
||||
outs := string(out)
|
||||
if !filepath.IsAbs(outs) {
|
||||
t.Fatalf("Child returned %q, want an absolute path", out)
|
||||
}
|
||||
if !sameFile(outs, ep) {
|
||||
t.Fatalf("Child returned %q, not the same file as %q", out, ep)
|
||||
}
|
||||
}
|
||||
|
||||
func sameFile(fn1, fn2 string) bool {
|
||||
fi1, err := os.Stat(fn1)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
fi2, err := os.Stat(fn2)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return os.SameFile(fi1, fi2)
|
||||
}
|
||||
|
||||
func init() {
|
||||
if e := os.Getenv(execPath_EnvVar); e != "" {
|
||||
// first chdir to another path
|
||||
dir := "/"
|
||||
if runtime.GOOS == "windows" {
|
||||
dir = filepath.VolumeName(".")
|
||||
}
|
||||
os.Chdir(dir)
|
||||
if ep, err := Executable(); err != nil {
|
||||
fmt.Fprint(os.Stderr, "ERROR: ", err)
|
||||
} else {
|
||||
fmt.Fprint(os.Stderr, ep)
|
||||
}
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
34
Godeps/_workspace/src/bitbucket.org/kardianos/osext/osext_windows.go
generated
vendored
Normal file
34
Godeps/_workspace/src/bitbucket.org/kardianos/osext/osext_windows.go
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package osext
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unicode/utf16"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var (
|
||||
kernel = syscall.MustLoadDLL("kernel32.dll")
|
||||
getModuleFileNameProc = kernel.MustFindProc("GetModuleFileNameW")
|
||||
)
|
||||
|
||||
// GetModuleFileName() with hModule = NULL
|
||||
func executable() (exePath string, err error) {
|
||||
return getModuleFileName()
|
||||
}
|
||||
|
||||
func getModuleFileName() (string, error) {
|
||||
var n uint32
|
||||
b := make([]uint16, syscall.MAX_PATH)
|
||||
size := uint32(len(b))
|
||||
|
||||
r0, _, e1 := getModuleFileNameProc.Call(0, uintptr(unsafe.Pointer(&b[0])), uintptr(size))
|
||||
n = uint32(r0)
|
||||
if n == 0 {
|
||||
return "", e1
|
||||
}
|
||||
return string(utf16.Decode(b[0:n])), nil
|
||||
}
|
||||
35
Godeps/_workspace/src/code.google.com/p/go.crypto/bcrypt/base64.go
generated
vendored
Normal file
35
Godeps/_workspace/src/code.google.com/p/go.crypto/bcrypt/base64.go
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package bcrypt
|
||||
|
||||
import "encoding/base64"
|
||||
|
||||
const alphabet = "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
||||
|
||||
var bcEncoding = base64.NewEncoding(alphabet)
|
||||
|
||||
func base64Encode(src []byte) []byte {
|
||||
n := bcEncoding.EncodedLen(len(src))
|
||||
dst := make([]byte, n)
|
||||
bcEncoding.Encode(dst, src)
|
||||
for dst[n-1] == '=' {
|
||||
n--
|
||||
}
|
||||
return dst[:n]
|
||||
}
|
||||
|
||||
func base64Decode(src []byte) ([]byte, error) {
|
||||
numOfEquals := 4 - (len(src) % 4)
|
||||
for i := 0; i < numOfEquals; i++ {
|
||||
src = append(src, '=')
|
||||
}
|
||||
|
||||
dst := make([]byte, bcEncoding.DecodedLen(len(src)))
|
||||
n, err := bcEncoding.Decode(dst, src)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dst[:n], nil
|
||||
}
|
||||
294
Godeps/_workspace/src/code.google.com/p/go.crypto/bcrypt/bcrypt.go
generated
vendored
Normal file
294
Godeps/_workspace/src/code.google.com/p/go.crypto/bcrypt/bcrypt.go
generated
vendored
Normal file
@@ -0,0 +1,294 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package bcrypt implements Provos and Mazières's bcrypt adaptive hashing
|
||||
// algorithm. See http://www.usenix.org/event/usenix99/provos/provos.pdf
|
||||
package bcrypt
|
||||
|
||||
// The code is a port of Provos and Mazières's C implementation.
|
||||
import (
|
||||
"code.google.com/p/go.crypto/blowfish"
|
||||
"crypto/rand"
|
||||
"crypto/subtle"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const (
|
||||
MinCost int = 4 // the minimum allowable cost as passed in to GenerateFromPassword
|
||||
MaxCost int = 31 // the maximum allowable cost as passed in to GenerateFromPassword
|
||||
DefaultCost int = 10 // the cost that will actually be set if a cost below MinCost is passed into GenerateFromPassword
|
||||
)
|
||||
|
||||
// The error returned from CompareHashAndPassword when a password and hash do
|
||||
// not match.
|
||||
var ErrMismatchedHashAndPassword = errors.New("crypto/bcrypt: hashedPassword is not the hash of the given password")
|
||||
|
||||
// The error returned from CompareHashAndPassword when a hash is too short to
|
||||
// be a bcrypt hash.
|
||||
var ErrHashTooShort = errors.New("crypto/bcrypt: hashedSecret too short to be a bcrypted password")
|
||||
|
||||
// The error returned from CompareHashAndPassword when a hash was created with
|
||||
// a bcrypt algorithm newer than this implementation.
|
||||
type HashVersionTooNewError byte
|
||||
|
||||
func (hv HashVersionTooNewError) Error() string {
|
||||
return fmt.Sprintf("crypto/bcrypt: bcrypt algorithm version '%c' requested is newer than current version '%c'", byte(hv), majorVersion)
|
||||
}
|
||||
|
||||
// The error returned from CompareHashAndPassword when a hash starts with something other than '$'
|
||||
type InvalidHashPrefixError byte
|
||||
|
||||
func (ih InvalidHashPrefixError) Error() string {
|
||||
return fmt.Sprintf("crypto/bcrypt: bcrypt hashes must start with '$', but hashedSecret started with '%c'", byte(ih))
|
||||
}
|
||||
|
||||
type InvalidCostError int
|
||||
|
||||
func (ic InvalidCostError) Error() string {
|
||||
return fmt.Sprintf("crypto/bcrypt: cost %d is outside allowed range (%d,%d)", int(ic), int(MinCost), int(MaxCost))
|
||||
}
|
||||
|
||||
const (
|
||||
majorVersion = '2'
|
||||
minorVersion = 'a'
|
||||
maxSaltSize = 16
|
||||
maxCryptedHashSize = 23
|
||||
encodedSaltSize = 22
|
||||
encodedHashSize = 31
|
||||
minHashSize = 59
|
||||
)
|
||||
|
||||
// magicCipherData is an IV for the 64 Blowfish encryption calls in
|
||||
// bcrypt(). It's the string "OrpheanBeholderScryDoubt" in big-endian bytes.
|
||||
var magicCipherData = []byte{
|
||||
0x4f, 0x72, 0x70, 0x68,
|
||||
0x65, 0x61, 0x6e, 0x42,
|
||||
0x65, 0x68, 0x6f, 0x6c,
|
||||
0x64, 0x65, 0x72, 0x53,
|
||||
0x63, 0x72, 0x79, 0x44,
|
||||
0x6f, 0x75, 0x62, 0x74,
|
||||
}
|
||||
|
||||
type hashed struct {
|
||||
hash []byte
|
||||
salt []byte
|
||||
cost int // allowed range is MinCost to MaxCost
|
||||
major byte
|
||||
minor byte
|
||||
}
|
||||
|
||||
// GenerateFromPassword returns the bcrypt hash of the password at the given
|
||||
// cost. If the cost given is less than MinCost, the cost will be set to
|
||||
// DefaultCost, instead. Use CompareHashAndPassword, as defined in this package,
|
||||
// to compare the returned hashed password with its cleartext version.
|
||||
func GenerateFromPassword(password []byte, cost int) ([]byte, error) {
|
||||
p, err := newFromPassword(password, cost)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return p.Hash(), nil
|
||||
}
|
||||
|
||||
// CompareHashAndPassword compares a bcrypt hashed password with its possible
|
||||
// plaintext equivalent. Returns nil on success, or an error on failure.
|
||||
func CompareHashAndPassword(hashedPassword, password []byte) error {
|
||||
p, err := newFromHash(hashedPassword)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
otherHash, err := bcrypt(password, p.cost, p.salt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
otherP := &hashed{otherHash, p.salt, p.cost, p.major, p.minor}
|
||||
if subtle.ConstantTimeCompare(p.Hash(), otherP.Hash()) == 1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return ErrMismatchedHashAndPassword
|
||||
}
|
||||
|
||||
// Cost returns the hashing cost used to create the given hashed
|
||||
// password. When, in the future, the hashing cost of a password system needs
|
||||
// to be increased in order to adjust for greater computational power, this
|
||||
// function allows one to establish which passwords need to be updated.
|
||||
func Cost(hashedPassword []byte) (int, error) {
|
||||
p, err := newFromHash(hashedPassword)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return p.cost, nil
|
||||
}
|
||||
|
||||
func newFromPassword(password []byte, cost int) (*hashed, error) {
|
||||
if cost < MinCost {
|
||||
cost = DefaultCost
|
||||
}
|
||||
p := new(hashed)
|
||||
p.major = majorVersion
|
||||
p.minor = minorVersion
|
||||
|
||||
err := checkCost(cost)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.cost = cost
|
||||
|
||||
unencodedSalt := make([]byte, maxSaltSize)
|
||||
_, err = io.ReadFull(rand.Reader, unencodedSalt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p.salt = base64Encode(unencodedSalt)
|
||||
hash, err := bcrypt(password, p.cost, p.salt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.hash = hash
|
||||
return p, err
|
||||
}
|
||||
|
||||
func newFromHash(hashedSecret []byte) (*hashed, error) {
|
||||
if len(hashedSecret) < minHashSize {
|
||||
return nil, ErrHashTooShort
|
||||
}
|
||||
p := new(hashed)
|
||||
n, err := p.decodeVersion(hashedSecret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hashedSecret = hashedSecret[n:]
|
||||
n, err = p.decodeCost(hashedSecret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hashedSecret = hashedSecret[n:]
|
||||
|
||||
// The "+2" is here because we'll have to append at most 2 '=' to the salt
|
||||
// when base64 decoding it in expensiveBlowfishSetup().
|
||||
p.salt = make([]byte, encodedSaltSize, encodedSaltSize+2)
|
||||
copy(p.salt, hashedSecret[:encodedSaltSize])
|
||||
|
||||
hashedSecret = hashedSecret[encodedSaltSize:]
|
||||
p.hash = make([]byte, len(hashedSecret))
|
||||
copy(p.hash, hashedSecret)
|
||||
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func bcrypt(password []byte, cost int, salt []byte) ([]byte, error) {
|
||||
cipherData := make([]byte, len(magicCipherData))
|
||||
copy(cipherData, magicCipherData)
|
||||
|
||||
c, err := expensiveBlowfishSetup(password, uint32(cost), salt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i := 0; i < 24; i += 8 {
|
||||
for j := 0; j < 64; j++ {
|
||||
c.Encrypt(cipherData[i:i+8], cipherData[i:i+8])
|
||||
}
|
||||
}
|
||||
|
||||
// Bug compatibility with C bcrypt implementations. We only encode 23 of
|
||||
// the 24 bytes encrypted.
|
||||
hsh := base64Encode(cipherData[:maxCryptedHashSize])
|
||||
return hsh, nil
|
||||
}
|
||||
|
||||
func expensiveBlowfishSetup(key []byte, cost uint32, salt []byte) (*blowfish.Cipher, error) {
|
||||
|
||||
csalt, err := base64Decode(salt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Bug compatibility with C bcrypt implementations. They use the trailing
|
||||
// NULL in the key string during expansion.
|
||||
ckey := append(key, 0)
|
||||
|
||||
c, err := blowfish.NewSaltedCipher(ckey, csalt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var i, rounds uint64
|
||||
rounds = 1 << cost
|
||||
for i = 0; i < rounds; i++ {
|
||||
blowfish.ExpandKey(ckey, c)
|
||||
blowfish.ExpandKey(csalt, c)
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func (p *hashed) Hash() []byte {
|
||||
arr := make([]byte, 60)
|
||||
arr[0] = '$'
|
||||
arr[1] = p.major
|
||||
n := 2
|
||||
if p.minor != 0 {
|
||||
arr[2] = p.minor
|
||||
n = 3
|
||||
}
|
||||
arr[n] = '$'
|
||||
n += 1
|
||||
copy(arr[n:], []byte(fmt.Sprintf("%02d", p.cost)))
|
||||
n += 2
|
||||
arr[n] = '$'
|
||||
n += 1
|
||||
copy(arr[n:], p.salt)
|
||||
n += encodedSaltSize
|
||||
copy(arr[n:], p.hash)
|
||||
n += encodedHashSize
|
||||
return arr[:n]
|
||||
}
|
||||
|
||||
func (p *hashed) decodeVersion(sbytes []byte) (int, error) {
|
||||
if sbytes[0] != '$' {
|
||||
return -1, InvalidHashPrefixError(sbytes[0])
|
||||
}
|
||||
if sbytes[1] > majorVersion {
|
||||
return -1, HashVersionTooNewError(sbytes[1])
|
||||
}
|
||||
p.major = sbytes[1]
|
||||
n := 3
|
||||
if sbytes[2] != '$' {
|
||||
p.minor = sbytes[2]
|
||||
n++
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// sbytes should begin where decodeVersion left off.
|
||||
func (p *hashed) decodeCost(sbytes []byte) (int, error) {
|
||||
cost, err := strconv.Atoi(string(sbytes[0:2]))
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
err = checkCost(cost)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
p.cost = cost
|
||||
return 3, nil
|
||||
}
|
||||
|
||||
func (p *hashed) String() string {
|
||||
return fmt.Sprintf("&{hash: %#v, salt: %#v, cost: %d, major: %c, minor: %c}", string(p.hash), p.salt, p.cost, p.major, p.minor)
|
||||
}
|
||||
|
||||
func checkCost(cost int) error {
|
||||
if cost < MinCost || cost > MaxCost {
|
||||
return InvalidCostError(cost)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
226
Godeps/_workspace/src/code.google.com/p/go.crypto/bcrypt/bcrypt_test.go
generated
vendored
Normal file
226
Godeps/_workspace/src/code.google.com/p/go.crypto/bcrypt/bcrypt_test.go
generated
vendored
Normal file
@@ -0,0 +1,226 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package bcrypt
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestBcryptingIsEasy(t *testing.T) {
|
||||
pass := []byte("mypassword")
|
||||
hp, err := GenerateFromPassword(pass, 0)
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateFromPassword error: %s", err)
|
||||
}
|
||||
|
||||
if CompareHashAndPassword(hp, pass) != nil {
|
||||
t.Errorf("%v should hash %s correctly", hp, pass)
|
||||
}
|
||||
|
||||
notPass := "notthepass"
|
||||
err = CompareHashAndPassword(hp, []byte(notPass))
|
||||
if err != ErrMismatchedHashAndPassword {
|
||||
t.Errorf("%v and %s should be mismatched", hp, notPass)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBcryptingIsCorrect(t *testing.T) {
|
||||
pass := []byte("allmine")
|
||||
salt := []byte("XajjQvNhvvRt5GSeFk1xFe")
|
||||
expectedHash := []byte("$2a$10$XajjQvNhvvRt5GSeFk1xFeyqRrsxkhBkUiQeg0dt.wU1qD4aFDcga")
|
||||
|
||||
hash, err := bcrypt(pass, 10, salt)
|
||||
if err != nil {
|
||||
t.Fatalf("bcrypt blew up: %v", err)
|
||||
}
|
||||
if !bytes.HasSuffix(expectedHash, hash) {
|
||||
t.Errorf("%v should be the suffix of %v", hash, expectedHash)
|
||||
}
|
||||
|
||||
h, err := newFromHash(expectedHash)
|
||||
if err != nil {
|
||||
t.Errorf("Unable to parse %s: %v", string(expectedHash), err)
|
||||
}
|
||||
|
||||
// This is not the safe way to compare these hashes. We do this only for
|
||||
// testing clarity. Use bcrypt.CompareHashAndPassword()
|
||||
if err == nil && !bytes.Equal(expectedHash, h.Hash()) {
|
||||
t.Errorf("Parsed hash %v should equal %v", h.Hash(), expectedHash)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVeryShortPasswords(t *testing.T) {
|
||||
key := []byte("k")
|
||||
salt := []byte("XajjQvNhvvRt5GSeFk1xFe")
|
||||
_, err := bcrypt(key, 10, salt)
|
||||
if err != nil {
|
||||
t.Errorf("One byte key resulted in error: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTooLongPasswordsWork(t *testing.T) {
|
||||
salt := []byte("XajjQvNhvvRt5GSeFk1xFe")
|
||||
// One byte over the usual 56 byte limit that blowfish has
|
||||
tooLongPass := []byte("012345678901234567890123456789012345678901234567890123456")
|
||||
tooLongExpected := []byte("$2a$10$XajjQvNhvvRt5GSeFk1xFe5l47dONXg781AmZtd869sO8zfsHuw7C")
|
||||
hash, err := bcrypt(tooLongPass, 10, salt)
|
||||
if err != nil {
|
||||
t.Fatalf("bcrypt blew up on long password: %v", err)
|
||||
}
|
||||
if !bytes.HasSuffix(tooLongExpected, hash) {
|
||||
t.Errorf("%v should be the suffix of %v", hash, tooLongExpected)
|
||||
}
|
||||
}
|
||||
|
||||
type InvalidHashTest struct {
|
||||
err error
|
||||
hash []byte
|
||||
}
|
||||
|
||||
var invalidTests = []InvalidHashTest{
|
||||
{ErrHashTooShort, []byte("$2a$10$fooo")},
|
||||
{ErrHashTooShort, []byte("$2a")},
|
||||
{HashVersionTooNewError('3'), []byte("$3a$10$sssssssssssssssssssssshhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh")},
|
||||
{InvalidHashPrefixError('%'), []byte("%2a$10$sssssssssssssssssssssshhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh")},
|
||||
{InvalidCostError(32), []byte("$2a$32$sssssssssssssssssssssshhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh")},
|
||||
}
|
||||
|
||||
func TestInvalidHashErrors(t *testing.T) {
|
||||
check := func(name string, expected, err error) {
|
||||
if err == nil {
|
||||
t.Errorf("%s: Should have returned an error", name)
|
||||
}
|
||||
if err != nil && err != expected {
|
||||
t.Errorf("%s gave err %v but should have given %v", name, err, expected)
|
||||
}
|
||||
}
|
||||
for _, iht := range invalidTests {
|
||||
_, err := newFromHash(iht.hash)
|
||||
check("newFromHash", iht.err, err)
|
||||
err = CompareHashAndPassword(iht.hash, []byte("anything"))
|
||||
check("CompareHashAndPassword", iht.err, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnpaddedBase64Encoding(t *testing.T) {
|
||||
original := []byte{101, 201, 101, 75, 19, 227, 199, 20, 239, 236, 133, 32, 30, 109, 243, 30}
|
||||
encodedOriginal := []byte("XajjQvNhvvRt5GSeFk1xFe")
|
||||
|
||||
encoded := base64Encode(original)
|
||||
|
||||
if !bytes.Equal(encodedOriginal, encoded) {
|
||||
t.Errorf("Encoded %v should have equaled %v", encoded, encodedOriginal)
|
||||
}
|
||||
|
||||
decoded, err := base64Decode(encodedOriginal)
|
||||
if err != nil {
|
||||
t.Fatalf("base64Decode blew up: %s", err)
|
||||
}
|
||||
|
||||
if !bytes.Equal(decoded, original) {
|
||||
t.Errorf("Decoded %v should have equaled %v", decoded, original)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCost(t *testing.T) {
|
||||
suffix := "XajjQvNhvvRt5GSeFk1xFe5l47dONXg781AmZtd869sO8zfsHuw7C"
|
||||
for _, vers := range []string{"2a", "2"} {
|
||||
for _, cost := range []int{4, 10} {
|
||||
s := fmt.Sprintf("$%s$%02d$%s", vers, cost, suffix)
|
||||
h := []byte(s)
|
||||
actual, err := Cost(h)
|
||||
if err != nil {
|
||||
t.Errorf("Cost, error: %s", err)
|
||||
continue
|
||||
}
|
||||
if actual != cost {
|
||||
t.Errorf("Cost, expected: %d, actual: %d", cost, actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
_, err := Cost([]byte("$a$a$" + suffix))
|
||||
if err == nil {
|
||||
t.Errorf("Cost, malformed but no error returned")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCostValidationInHash(t *testing.T) {
|
||||
if testing.Short() {
|
||||
return
|
||||
}
|
||||
|
||||
pass := []byte("mypassword")
|
||||
|
||||
for c := 0; c < MinCost; c++ {
|
||||
p, _ := newFromPassword(pass, c)
|
||||
if p.cost != DefaultCost {
|
||||
t.Errorf("newFromPassword should default costs below %d to %d, but was %d", MinCost, DefaultCost, p.cost)
|
||||
}
|
||||
}
|
||||
|
||||
p, _ := newFromPassword(pass, 14)
|
||||
if p.cost != 14 {
|
||||
t.Errorf("newFromPassword should default cost to 14, but was %d", p.cost)
|
||||
}
|
||||
|
||||
hp, _ := newFromHash(p.Hash())
|
||||
if p.cost != hp.cost {
|
||||
t.Errorf("newFromHash should maintain the cost at %d, but was %d", p.cost, hp.cost)
|
||||
}
|
||||
|
||||
_, err := newFromPassword(pass, 32)
|
||||
if err == nil {
|
||||
t.Fatalf("newFromPassword: should return a cost error")
|
||||
}
|
||||
if err != InvalidCostError(32) {
|
||||
t.Errorf("newFromPassword: should return cost error, got %#v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCostReturnsWithLeadingZeroes(t *testing.T) {
|
||||
hp, _ := newFromPassword([]byte("abcdefgh"), 7)
|
||||
cost := hp.Hash()[4:7]
|
||||
expected := []byte("07$")
|
||||
|
||||
if !bytes.Equal(expected, cost) {
|
||||
t.Errorf("single digit costs in hash should have leading zeros: was %v instead of %v", cost, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMinorNotRequired(t *testing.T) {
|
||||
noMinorHash := []byte("$2$10$XajjQvNhvvRt5GSeFk1xFeyqRrsxkhBkUiQeg0dt.wU1qD4aFDcga")
|
||||
h, err := newFromHash(noMinorHash)
|
||||
if err != nil {
|
||||
t.Fatalf("No minor hash blew up: %s", err)
|
||||
}
|
||||
if h.minor != 0 {
|
||||
t.Errorf("Should leave minor version at 0, but was %d", h.minor)
|
||||
}
|
||||
|
||||
if !bytes.Equal(noMinorHash, h.Hash()) {
|
||||
t.Errorf("Should generate hash %v, but created %v", noMinorHash, h.Hash())
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkEqual(b *testing.B) {
|
||||
b.StopTimer()
|
||||
passwd := []byte("somepasswordyoulike")
|
||||
hash, _ := GenerateFromPassword(passwd, 10)
|
||||
b.StartTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
CompareHashAndPassword(hash, passwd)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGeneration(b *testing.B) {
|
||||
b.StopTimer()
|
||||
passwd := []byte("mylongpassword1234")
|
||||
b.StartTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
GenerateFromPassword(passwd, 10)
|
||||
}
|
||||
}
|
||||
190
Godeps/_workspace/src/code.google.com/p/go.crypto/blowfish/block.go
generated
vendored
Normal file
190
Godeps/_workspace/src/code.google.com/p/go.crypto/blowfish/block.go
generated
vendored
Normal file
@@ -0,0 +1,190 @@
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package blowfish
|
||||
|
||||
// ExpandKey performs a key expansion on the given *Cipher. Specifically, it
|
||||
// performs the Blowfish algorithm's key schedule which sets up the *Cipher's
|
||||
// pi and substitution tables for calls to Encrypt. This is used, primarily,
|
||||
// by the bcrypt package to reuse the Blowfish key schedule during its
|
||||
// set up. It's unlikely that you need to use this directly.
|
||||
func ExpandKey(key []byte, c *Cipher) {
|
||||
j := 0
|
||||
for i := 0; i < 18; i++ {
|
||||
var d uint32
|
||||
for k := 0; k < 4; k++ {
|
||||
d = d<<8 | uint32(key[j])
|
||||
j++
|
||||
if j >= len(key) {
|
||||
j = 0
|
||||
}
|
||||
}
|
||||
c.p[i] ^= d
|
||||
}
|
||||
|
||||
var l, r uint32
|
||||
for i := 0; i < 18; i += 2 {
|
||||
l, r = encryptBlock(l, r, c)
|
||||
c.p[i], c.p[i+1] = l, r
|
||||
}
|
||||
|
||||
for i := 0; i < 256; i += 2 {
|
||||
l, r = encryptBlock(l, r, c)
|
||||
c.s0[i], c.s0[i+1] = l, r
|
||||
}
|
||||
for i := 0; i < 256; i += 2 {
|
||||
l, r = encryptBlock(l, r, c)
|
||||
c.s1[i], c.s1[i+1] = l, r
|
||||
}
|
||||
for i := 0; i < 256; i += 2 {
|
||||
l, r = encryptBlock(l, r, c)
|
||||
c.s2[i], c.s2[i+1] = l, r
|
||||
}
|
||||
for i := 0; i < 256; i += 2 {
|
||||
l, r = encryptBlock(l, r, c)
|
||||
c.s3[i], c.s3[i+1] = l, r
|
||||
}
|
||||
}
|
||||
|
||||
// This is similar to ExpandKey, but folds the salt during the key
|
||||
// schedule. While ExpandKey is essentially expandKeyWithSalt with an all-zero
|
||||
// salt passed in, reusing ExpandKey turns out to be a place of inefficiency
|
||||
// and specializing it here is useful.
|
||||
func expandKeyWithSalt(key []byte, salt []byte, c *Cipher) {
|
||||
j := 0
|
||||
for i := 0; i < 18; i++ {
|
||||
var d uint32
|
||||
for k := 0; k < 4; k++ {
|
||||
d = d<<8 | uint32(key[j])
|
||||
j++
|
||||
if j >= len(key) {
|
||||
j = 0
|
||||
}
|
||||
}
|
||||
c.p[i] ^= d
|
||||
}
|
||||
|
||||
j = 0
|
||||
var expandedSalt [4]uint32
|
||||
for i := range expandedSalt {
|
||||
var d uint32
|
||||
for k := 0; k < 4; k++ {
|
||||
d = d<<8 | uint32(salt[j])
|
||||
j++
|
||||
if j >= len(salt) {
|
||||
j = 0
|
||||
}
|
||||
}
|
||||
expandedSalt[i] = d
|
||||
}
|
||||
|
||||
var l, r uint32
|
||||
for i := 0; i < 18; i += 2 {
|
||||
l ^= expandedSalt[i&2]
|
||||
r ^= expandedSalt[(i&2)+1]
|
||||
l, r = encryptBlock(l, r, c)
|
||||
c.p[i], c.p[i+1] = l, r
|
||||
}
|
||||
|
||||
for i := 0; i < 256; i += 4 {
|
||||
l ^= expandedSalt[2]
|
||||
r ^= expandedSalt[3]
|
||||
l, r = encryptBlock(l, r, c)
|
||||
c.s0[i], c.s0[i+1] = l, r
|
||||
|
||||
l ^= expandedSalt[0]
|
||||
r ^= expandedSalt[1]
|
||||
l, r = encryptBlock(l, r, c)
|
||||
c.s0[i+2], c.s0[i+3] = l, r
|
||||
|
||||
}
|
||||
|
||||
for i := 0; i < 256; i += 4 {
|
||||
l ^= expandedSalt[2]
|
||||
r ^= expandedSalt[3]
|
||||
l, r = encryptBlock(l, r, c)
|
||||
c.s1[i], c.s1[i+1] = l, r
|
||||
|
||||
l ^= expandedSalt[0]
|
||||
r ^= expandedSalt[1]
|
||||
l, r = encryptBlock(l, r, c)
|
||||
c.s1[i+2], c.s1[i+3] = l, r
|
||||
}
|
||||
|
||||
for i := 0; i < 256; i += 4 {
|
||||
l ^= expandedSalt[2]
|
||||
r ^= expandedSalt[3]
|
||||
l, r = encryptBlock(l, r, c)
|
||||
c.s2[i], c.s2[i+1] = l, r
|
||||
|
||||
l ^= expandedSalt[0]
|
||||
r ^= expandedSalt[1]
|
||||
l, r = encryptBlock(l, r, c)
|
||||
c.s2[i+2], c.s2[i+3] = l, r
|
||||
}
|
||||
|
||||
for i := 0; i < 256; i += 4 {
|
||||
l ^= expandedSalt[2]
|
||||
r ^= expandedSalt[3]
|
||||
l, r = encryptBlock(l, r, c)
|
||||
c.s3[i], c.s3[i+1] = l, r
|
||||
|
||||
l ^= expandedSalt[0]
|
||||
r ^= expandedSalt[1]
|
||||
l, r = encryptBlock(l, r, c)
|
||||
c.s3[i+2], c.s3[i+3] = l, r
|
||||
}
|
||||
}
|
||||
|
||||
func encryptBlock(l, r uint32, c *Cipher) (uint32, uint32) {
|
||||
xl, xr := l, r
|
||||
xl ^= c.p[0]
|
||||
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[1]
|
||||
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[2]
|
||||
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[3]
|
||||
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[4]
|
||||
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[5]
|
||||
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[6]
|
||||
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[7]
|
||||
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[8]
|
||||
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[9]
|
||||
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[10]
|
||||
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[11]
|
||||
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[12]
|
||||
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[13]
|
||||
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[14]
|
||||
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[15]
|
||||
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[16]
|
||||
xr ^= c.p[17]
|
||||
return xr, xl
|
||||
}
|
||||
|
||||
func decryptBlock(l, r uint32, c *Cipher) (uint32, uint32) {
|
||||
xl, xr := l, r
|
||||
xl ^= c.p[17]
|
||||
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[16]
|
||||
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[15]
|
||||
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[14]
|
||||
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[13]
|
||||
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[12]
|
||||
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[11]
|
||||
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[10]
|
||||
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[9]
|
||||
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[8]
|
||||
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[7]
|
||||
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[6]
|
||||
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[5]
|
||||
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[4]
|
||||
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[3]
|
||||
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[2]
|
||||
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[1]
|
||||
xr ^= c.p[0]
|
||||
return xr, xl
|
||||
}
|
||||
|
||||
func zero(x []uint32) {
|
||||
for i := range x {
|
||||
x[i] = 0
|
||||
}
|
||||
}
|
||||
204
Godeps/_workspace/src/code.google.com/p/go.crypto/blowfish/blowfish_test.go
generated
vendored
Normal file
204
Godeps/_workspace/src/code.google.com/p/go.crypto/blowfish/blowfish_test.go
generated
vendored
Normal file
@@ -0,0 +1,204 @@
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package blowfish
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
type CryptTest struct {
|
||||
key []byte
|
||||
in []byte
|
||||
out []byte
|
||||
}
|
||||
|
||||
// Test vector values are from http://www.schneier.com/code/vectors.txt.
|
||||
var encryptTests = []CryptTest{
|
||||
{
|
||||
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
[]byte{0x4E, 0xF9, 0x97, 0x45, 0x61, 0x98, 0xDD, 0x78}},
|
||||
{
|
||||
[]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
|
||||
[]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
|
||||
[]byte{0x51, 0x86, 0x6F, 0xD5, 0xB8, 0x5E, 0xCB, 0x8A}},
|
||||
{
|
||||
[]byte{0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
[]byte{0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
|
||||
[]byte{0x7D, 0x85, 0x6F, 0x9A, 0x61, 0x30, 0x63, 0xF2}},
|
||||
{
|
||||
[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11},
|
||||
[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11},
|
||||
[]byte{0x24, 0x66, 0xDD, 0x87, 0x8B, 0x96, 0x3C, 0x9D}},
|
||||
|
||||
{
|
||||
[]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
|
||||
[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11},
|
||||
[]byte{0x61, 0xF9, 0xC3, 0x80, 0x22, 0x81, 0xB0, 0x96}},
|
||||
{
|
||||
[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11},
|
||||
[]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
|
||||
[]byte{0x7D, 0x0C, 0xC6, 0x30, 0xAF, 0xDA, 0x1E, 0xC7}},
|
||||
{
|
||||
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
[]byte{0x4E, 0xF9, 0x97, 0x45, 0x61, 0x98, 0xDD, 0x78}},
|
||||
{
|
||||
[]byte{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10},
|
||||
[]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
|
||||
[]byte{0x0A, 0xCE, 0xAB, 0x0F, 0xC6, 0xA0, 0xA2, 0x8D}},
|
||||
{
|
||||
[]byte{0x7C, 0xA1, 0x10, 0x45, 0x4A, 0x1A, 0x6E, 0x57},
|
||||
[]byte{0x01, 0xA1, 0xD6, 0xD0, 0x39, 0x77, 0x67, 0x42},
|
||||
[]byte{0x59, 0xC6, 0x82, 0x45, 0xEB, 0x05, 0x28, 0x2B}},
|
||||
{
|
||||
[]byte{0x01, 0x31, 0xD9, 0x61, 0x9D, 0xC1, 0x37, 0x6E},
|
||||
[]byte{0x5C, 0xD5, 0x4C, 0xA8, 0x3D, 0xEF, 0x57, 0xDA},
|
||||
[]byte{0xB1, 0xB8, 0xCC, 0x0B, 0x25, 0x0F, 0x09, 0xA0}},
|
||||
{
|
||||
[]byte{0x07, 0xA1, 0x13, 0x3E, 0x4A, 0x0B, 0x26, 0x86},
|
||||
[]byte{0x02, 0x48, 0xD4, 0x38, 0x06, 0xF6, 0x71, 0x72},
|
||||
[]byte{0x17, 0x30, 0xE5, 0x77, 0x8B, 0xEA, 0x1D, 0xA4}},
|
||||
{
|
||||
[]byte{0x38, 0x49, 0x67, 0x4C, 0x26, 0x02, 0x31, 0x9E},
|
||||
[]byte{0x51, 0x45, 0x4B, 0x58, 0x2D, 0xDF, 0x44, 0x0A},
|
||||
[]byte{0xA2, 0x5E, 0x78, 0x56, 0xCF, 0x26, 0x51, 0xEB}},
|
||||
{
|
||||
[]byte{0x04, 0xB9, 0x15, 0xBA, 0x43, 0xFE, 0xB5, 0xB6},
|
||||
[]byte{0x42, 0xFD, 0x44, 0x30, 0x59, 0x57, 0x7F, 0xA2},
|
||||
[]byte{0x35, 0x38, 0x82, 0xB1, 0x09, 0xCE, 0x8F, 0x1A}},
|
||||
{
|
||||
[]byte{0x01, 0x13, 0xB9, 0x70, 0xFD, 0x34, 0xF2, 0xCE},
|
||||
[]byte{0x05, 0x9B, 0x5E, 0x08, 0x51, 0xCF, 0x14, 0x3A},
|
||||
[]byte{0x48, 0xF4, 0xD0, 0x88, 0x4C, 0x37, 0x99, 0x18}},
|
||||
{
|
||||
[]byte{0x01, 0x70, 0xF1, 0x75, 0x46, 0x8F, 0xB5, 0xE6},
|
||||
[]byte{0x07, 0x56, 0xD8, 0xE0, 0x77, 0x47, 0x61, 0xD2},
|
||||
[]byte{0x43, 0x21, 0x93, 0xB7, 0x89, 0x51, 0xFC, 0x98}},
|
||||
{
|
||||
[]byte{0x43, 0x29, 0x7F, 0xAD, 0x38, 0xE3, 0x73, 0xFE},
|
||||
[]byte{0x76, 0x25, 0x14, 0xB8, 0x29, 0xBF, 0x48, 0x6A},
|
||||
[]byte{0x13, 0xF0, 0x41, 0x54, 0xD6, 0x9D, 0x1A, 0xE5}},
|
||||
{
|
||||
[]byte{0x07, 0xA7, 0x13, 0x70, 0x45, 0xDA, 0x2A, 0x16},
|
||||
[]byte{0x3B, 0xDD, 0x11, 0x90, 0x49, 0x37, 0x28, 0x02},
|
||||
[]byte{0x2E, 0xED, 0xDA, 0x93, 0xFF, 0xD3, 0x9C, 0x79}},
|
||||
{
|
||||
[]byte{0x04, 0x68, 0x91, 0x04, 0xC2, 0xFD, 0x3B, 0x2F},
|
||||
[]byte{0x26, 0x95, 0x5F, 0x68, 0x35, 0xAF, 0x60, 0x9A},
|
||||
[]byte{0xD8, 0x87, 0xE0, 0x39, 0x3C, 0x2D, 0xA6, 0xE3}},
|
||||
{
|
||||
[]byte{0x37, 0xD0, 0x6B, 0xB5, 0x16, 0xCB, 0x75, 0x46},
|
||||
[]byte{0x16, 0x4D, 0x5E, 0x40, 0x4F, 0x27, 0x52, 0x32},
|
||||
[]byte{0x5F, 0x99, 0xD0, 0x4F, 0x5B, 0x16, 0x39, 0x69}},
|
||||
{
|
||||
[]byte{0x1F, 0x08, 0x26, 0x0D, 0x1A, 0xC2, 0x46, 0x5E},
|
||||
[]byte{0x6B, 0x05, 0x6E, 0x18, 0x75, 0x9F, 0x5C, 0xCA},
|
||||
[]byte{0x4A, 0x05, 0x7A, 0x3B, 0x24, 0xD3, 0x97, 0x7B}},
|
||||
{
|
||||
[]byte{0x58, 0x40, 0x23, 0x64, 0x1A, 0xBA, 0x61, 0x76},
|
||||
[]byte{0x00, 0x4B, 0xD6, 0xEF, 0x09, 0x17, 0x60, 0x62},
|
||||
[]byte{0x45, 0x20, 0x31, 0xC1, 0xE4, 0xFA, 0xDA, 0x8E}},
|
||||
{
|
||||
[]byte{0x02, 0x58, 0x16, 0x16, 0x46, 0x29, 0xB0, 0x07},
|
||||
[]byte{0x48, 0x0D, 0x39, 0x00, 0x6E, 0xE7, 0x62, 0xF2},
|
||||
[]byte{0x75, 0x55, 0xAE, 0x39, 0xF5, 0x9B, 0x87, 0xBD}},
|
||||
{
|
||||
[]byte{0x49, 0x79, 0x3E, 0xBC, 0x79, 0xB3, 0x25, 0x8F},
|
||||
[]byte{0x43, 0x75, 0x40, 0xC8, 0x69, 0x8F, 0x3C, 0xFA},
|
||||
[]byte{0x53, 0xC5, 0x5F, 0x9C, 0xB4, 0x9F, 0xC0, 0x19}},
|
||||
{
|
||||
[]byte{0x4F, 0xB0, 0x5E, 0x15, 0x15, 0xAB, 0x73, 0xA7},
|
||||
[]byte{0x07, 0x2D, 0x43, 0xA0, 0x77, 0x07, 0x52, 0x92},
|
||||
[]byte{0x7A, 0x8E, 0x7B, 0xFA, 0x93, 0x7E, 0x89, 0xA3}},
|
||||
{
|
||||
[]byte{0x49, 0xE9, 0x5D, 0x6D, 0x4C, 0xA2, 0x29, 0xBF},
|
||||
[]byte{0x02, 0xFE, 0x55, 0x77, 0x81, 0x17, 0xF1, 0x2A},
|
||||
[]byte{0xCF, 0x9C, 0x5D, 0x7A, 0x49, 0x86, 0xAD, 0xB5}},
|
||||
{
|
||||
[]byte{0x01, 0x83, 0x10, 0xDC, 0x40, 0x9B, 0x26, 0xD6},
|
||||
[]byte{0x1D, 0x9D, 0x5C, 0x50, 0x18, 0xF7, 0x28, 0xC2},
|
||||
[]byte{0xD1, 0xAB, 0xB2, 0x90, 0x65, 0x8B, 0xC7, 0x78}},
|
||||
{
|
||||
[]byte{0x1C, 0x58, 0x7F, 0x1C, 0x13, 0x92, 0x4F, 0xEF},
|
||||
[]byte{0x30, 0x55, 0x32, 0x28, 0x6D, 0x6F, 0x29, 0x5A},
|
||||
[]byte{0x55, 0xCB, 0x37, 0x74, 0xD1, 0x3E, 0xF2, 0x01}},
|
||||
{
|
||||
[]byte{0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
|
||||
[]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
|
||||
[]byte{0xFA, 0x34, 0xEC, 0x48, 0x47, 0xB2, 0x68, 0xB2}},
|
||||
{
|
||||
[]byte{0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E},
|
||||
[]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
|
||||
[]byte{0xA7, 0x90, 0x79, 0x51, 0x08, 0xEA, 0x3C, 0xAE}},
|
||||
{
|
||||
[]byte{0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE},
|
||||
[]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
|
||||
[]byte{0xC3, 0x9E, 0x07, 0x2D, 0x9F, 0xAC, 0x63, 0x1D}},
|
||||
{
|
||||
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
[]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
|
||||
[]byte{0x01, 0x49, 0x33, 0xE0, 0xCD, 0xAF, 0xF6, 0xE4}},
|
||||
{
|
||||
[]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
|
||||
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
[]byte{0xF2, 0x1E, 0x9A, 0x77, 0xB7, 0x1C, 0x49, 0xBC}},
|
||||
{
|
||||
[]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
|
||||
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
[]byte{0x24, 0x59, 0x46, 0x88, 0x57, 0x54, 0x36, 0x9A}},
|
||||
{
|
||||
[]byte{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10},
|
||||
[]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
|
||||
[]byte{0x6B, 0x5C, 0x5A, 0x9C, 0x5D, 0x9E, 0x0A, 0x5A}},
|
||||
}
|
||||
|
||||
func TestCipherEncrypt(t *testing.T) {
|
||||
for i, tt := range encryptTests {
|
||||
c, err := NewCipher(tt.key)
|
||||
if err != nil {
|
||||
t.Errorf("NewCipher(%d bytes) = %s", len(tt.key), err)
|
||||
continue
|
||||
}
|
||||
ct := make([]byte, len(tt.out))
|
||||
c.Encrypt(ct, tt.in)
|
||||
for j, v := range ct {
|
||||
if v != tt.out[j] {
|
||||
t.Errorf("Cipher.Encrypt, test vector #%d: cipher-text[%d] = %#x, expected %#x", i, j, v, tt.out[j])
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCipherDecrypt(t *testing.T) {
|
||||
for i, tt := range encryptTests {
|
||||
c, err := NewCipher(tt.key)
|
||||
if err != nil {
|
||||
t.Errorf("NewCipher(%d bytes) = %s", len(tt.key), err)
|
||||
continue
|
||||
}
|
||||
pt := make([]byte, len(tt.in))
|
||||
c.Decrypt(pt, tt.out)
|
||||
for j, v := range pt {
|
||||
if v != tt.in[j] {
|
||||
t.Errorf("Cipher.Decrypt, test vector #%d: plain-text[%d] = %#x, expected %#x", i, j, v, tt.in[j])
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSaltedCipherKeyLength(t *testing.T) {
|
||||
if _, err := NewSaltedCipher(nil, []byte{'a'}); err != KeySizeError(0) {
|
||||
t.Errorf("NewSaltedCipher with short key, gave error %#v, expected %#v", err, KeySizeError(0))
|
||||
}
|
||||
|
||||
// A 57-byte key. One over the typical blowfish restriction.
|
||||
key := []byte("012345678901234567890123456789012345678901234567890123456")
|
||||
if _, err := NewSaltedCipher(key, []byte{'a'}); err != nil {
|
||||
t.Errorf("NewSaltedCipher with long key, gave error %#v", err)
|
||||
}
|
||||
}
|
||||
88
Godeps/_workspace/src/code.google.com/p/go.crypto/blowfish/cipher.go
generated
vendored
Normal file
88
Godeps/_workspace/src/code.google.com/p/go.crypto/blowfish/cipher.go
generated
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package blowfish implements Bruce Schneier's Blowfish encryption algorithm.
|
||||
package blowfish
|
||||
|
||||
// The code is a port of Bruce Schneier's C implementation.
|
||||
// See http://www.schneier.com/blowfish.html.
|
||||
|
||||
import "strconv"
|
||||
|
||||
// The Blowfish block size in bytes.
|
||||
const BlockSize = 8
|
||||
|
||||
// A Cipher is an instance of Blowfish encryption using a particular key.
|
||||
type Cipher struct {
|
||||
p [18]uint32
|
||||
s0, s1, s2, s3 [256]uint32
|
||||
}
|
||||
|
||||
type KeySizeError int
|
||||
|
||||
func (k KeySizeError) Error() string {
|
||||
return "crypto/blowfish: invalid key size " + strconv.Itoa(int(k))
|
||||
}
|
||||
|
||||
// NewCipher creates and returns a Cipher.
|
||||
// The key argument should be the Blowfish key, from 1 to 56 bytes.
|
||||
func NewCipher(key []byte) (*Cipher, error) {
|
||||
var result Cipher
|
||||
if k := len(key); k < 1 || k > 56 {
|
||||
return nil, KeySizeError(k)
|
||||
}
|
||||
initCipher(&result)
|
||||
ExpandKey(key, &result)
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// NewSaltedCipher creates a returns a Cipher that folds a salt into its key
|
||||
// schedule. For most purposes, NewCipher, instead of NewSaltedCipher, is
|
||||
// sufficient and desirable. For bcrypt compatiblity, the key can be over 56
|
||||
// bytes. Only the first 16 bytes of salt are used.
|
||||
func NewSaltedCipher(key, salt []byte) (*Cipher, error) {
|
||||
var result Cipher
|
||||
if k := len(key); k < 1 {
|
||||
return nil, KeySizeError(k)
|
||||
}
|
||||
initCipher(&result)
|
||||
expandKeyWithSalt(key, salt, &result)
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// BlockSize returns the Blowfish block size, 8 bytes.
|
||||
// It is necessary to satisfy the Block interface in the
|
||||
// package "crypto/cipher".
|
||||
func (c *Cipher) BlockSize() int { return BlockSize }
|
||||
|
||||
// Encrypt encrypts the 8-byte buffer src using the key k
|
||||
// and stores the result in dst.
|
||||
// Note that for amounts of data larger than a block,
|
||||
// it is not safe to just call Encrypt on successive blocks;
|
||||
// instead, use an encryption mode like CBC (see crypto/cipher/cbc.go).
|
||||
func (c *Cipher) Encrypt(dst, src []byte) {
|
||||
l := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint32(src[3])
|
||||
r := uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint32(src[7])
|
||||
l, r = encryptBlock(l, r, c)
|
||||
dst[0], dst[1], dst[2], dst[3] = byte(l>>24), byte(l>>16), byte(l>>8), byte(l)
|
||||
dst[4], dst[5], dst[6], dst[7] = byte(r>>24), byte(r>>16), byte(r>>8), byte(r)
|
||||
}
|
||||
|
||||
// Decrypt decrypts the 8-byte buffer src using the key k
|
||||
// and stores the result in dst.
|
||||
func (c *Cipher) Decrypt(dst, src []byte) {
|
||||
l := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint32(src[3])
|
||||
r := uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint32(src[7])
|
||||
l, r = decryptBlock(l, r, c)
|
||||
dst[0], dst[1], dst[2], dst[3] = byte(l>>24), byte(l>>16), byte(l>>8), byte(l)
|
||||
dst[4], dst[5], dst[6], dst[7] = byte(r>>24), byte(r>>16), byte(r>>8), byte(r)
|
||||
}
|
||||
|
||||
func initCipher(c *Cipher) {
|
||||
copy(c.p[0:], p[0:])
|
||||
copy(c.s0[0:], s0[0:])
|
||||
copy(c.s1[0:], s1[0:])
|
||||
copy(c.s2[0:], s2[0:])
|
||||
copy(c.s3[0:], s3[0:])
|
||||
}
|
||||
199
Godeps/_workspace/src/code.google.com/p/go.crypto/blowfish/const.go
generated
vendored
Normal file
199
Godeps/_workspace/src/code.google.com/p/go.crypto/blowfish/const.go
generated
vendored
Normal file
@@ -0,0 +1,199 @@
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// The startup permutation array and substitution boxes.
|
||||
// They are the hexadecimal digits of PI; see:
|
||||
// http://www.schneier.com/code/constants.txt.
|
||||
|
||||
package blowfish
|
||||
|
||||
var s0 = [256]uint32{
|
||||
0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96,
|
||||
0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
|
||||
0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658,
|
||||
0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
|
||||
0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e,
|
||||
0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
|
||||
0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 0x55ca396a, 0x2aab10b6,
|
||||
0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
|
||||
0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c,
|
||||
0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
|
||||
0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, 0xe98575b1,
|
||||
0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
|
||||
0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a,
|
||||
0x670c9c61, 0xabd388f0, 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
|
||||
0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176,
|
||||
0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
|
||||
0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706,
|
||||
0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
|
||||
0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b,
|
||||
0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
|
||||
0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c,
|
||||
0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
|
||||
0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a,
|
||||
0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
|
||||
0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760,
|
||||
0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
|
||||
0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 0x695b27b0, 0xbbca58c8,
|
||||
0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
|
||||
0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33,
|
||||
0x62fb1341, 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
|
||||
0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, 0xafc725e0,
|
||||
0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
|
||||
0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777,
|
||||
0xea752dfe, 0x8b021fa1, 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
|
||||
0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705,
|
||||
0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
|
||||
0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e,
|
||||
0x226800bb, 0x57b8e0af, 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
|
||||
0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9,
|
||||
0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
|
||||
0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f,
|
||||
0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
|
||||
0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a,
|
||||
}
|
||||
|
||||
var s1 = [256]uint32{
|
||||
0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d,
|
||||
0x9cee60b8, 0x8fedb266, 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
|
||||
0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65,
|
||||
0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
|
||||
0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9,
|
||||
0x3c971814, 0x6b6a70a1, 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
|
||||
0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, 0xb03ada37, 0xf0500c0d,
|
||||
0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
|
||||
0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc,
|
||||
0xc8b57634, 0x9af3dda7, 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
|
||||
0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, 0x4e548b38, 0x4f6db908,
|
||||
0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
|
||||
0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124,
|
||||
0x501adde6, 0x9f84cd87, 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
|
||||
0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 0xef1c1847, 0x3215d908,
|
||||
0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
|
||||
0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b,
|
||||
0x3c11183b, 0x5924a509, 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
|
||||
0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa,
|
||||
0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
|
||||
0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d,
|
||||
0x1939260f, 0x19c27960, 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
|
||||
0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5,
|
||||
0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
|
||||
0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96,
|
||||
0x0334fe1e, 0xaa0363cf, 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
|
||||
0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca,
|
||||
0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
|
||||
0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77,
|
||||
0x11ed935f, 0x16681281, 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
|
||||
0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, 0xcdb30aeb, 0x532e3054,
|
||||
0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
|
||||
0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea,
|
||||
0xdb6c4f15, 0xfacb4fd0, 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
|
||||
0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, 0xcf62a1f2, 0x5b8d2646,
|
||||
0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
|
||||
0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea,
|
||||
0x1dadf43e, 0x233f7061, 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
|
||||
0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e,
|
||||
0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
|
||||
0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd,
|
||||
0x675fda79, 0xe3674340, 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
|
||||
0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7,
|
||||
}
|
||||
|
||||
var s2 = [256]uint32{
|
||||
0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7,
|
||||
0xbcf46b2e, 0xd4a20068, 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
|
||||
0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, 0x4d95fc1d, 0x96b591af,
|
||||
0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
|
||||
0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4,
|
||||
0x0a2c86da, 0xe9b66dfb, 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
|
||||
0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, 0xaace1e7c, 0xd3375fec,
|
||||
0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
|
||||
0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332,
|
||||
0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
|
||||
0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, 0x55a867bc, 0xa1159a58,
|
||||
0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
|
||||
0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22,
|
||||
0x48c1133f, 0xc70f86dc, 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
|
||||
0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, 0x257b7834, 0x602a9c60,
|
||||
0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
|
||||
0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99,
|
||||
0xde720c8c, 0x2da2f728, 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
|
||||
0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, 0x0a476341, 0x992eff74,
|
||||
0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
|
||||
0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3,
|
||||
0xb5390f92, 0x690fed0b, 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
|
||||
0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, 0x37392eb3, 0xcc115979,
|
||||
0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
|
||||
0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa,
|
||||
0x3d25bdd8, 0xe2e1c3c9, 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
|
||||
0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, 0x9dbc8057, 0xf0f7c086,
|
||||
0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
|
||||
0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24,
|
||||
0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
|
||||
0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, 0x7aeb2661, 0x8b1ddf84,
|
||||
0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
|
||||
0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09,
|
||||
0x662d09a1, 0xc4324633, 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
|
||||
0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, 0xdcb7da83, 0x573906fe,
|
||||
0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
|
||||
0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0,
|
||||
0x006058aa, 0x30dc7d62, 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
|
||||
0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, 0x6f05e409, 0x4b7c0188,
|
||||
0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
|
||||
0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8,
|
||||
0xa28514d9, 0x6c51133c, 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
|
||||
0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0,
|
||||
}
|
||||
|
||||
var s3 = [256]uint32{
|
||||
0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742,
|
||||
0xd3822740, 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
|
||||
0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f, 0xbc946e79,
|
||||
0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
|
||||
0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a,
|
||||
0x63ef8ce2, 0x9a86ee22, 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
|
||||
0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, 0x2826a2f9, 0xa73a3ae1,
|
||||
0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
|
||||
0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797,
|
||||
0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
|
||||
0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, 0xe029ac71, 0xe019a5e6,
|
||||
0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
|
||||
0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba,
|
||||
0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
|
||||
0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, 0x7533d928, 0xb155fdf5,
|
||||
0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
|
||||
0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce,
|
||||
0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
|
||||
0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, 0xb39a460a, 0x6445c0dd,
|
||||
0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
|
||||
0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb,
|
||||
0x8d6612ae, 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
|
||||
0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 0x4040cb08, 0x4eb4e2cc,
|
||||
0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
|
||||
0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc,
|
||||
0xbb3a792b, 0x344525bd, 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
|
||||
0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 0x1a908749, 0xd44fbd9a,
|
||||
0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
|
||||
0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a,
|
||||
0x0f91fc71, 0x9b941525, 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
|
||||
0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b,
|
||||
0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
|
||||
0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e,
|
||||
0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
|
||||
0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, 0xf523f357, 0xa6327623,
|
||||
0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
|
||||
0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a,
|
||||
0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
|
||||
0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, 0x53113ec0, 0x1640e3d3,
|
||||
0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
|
||||
0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c,
|
||||
0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
|
||||
0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6,
|
||||
}
|
||||
|
||||
var p = [18]uint32{
|
||||
0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0,
|
||||
0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
|
||||
0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b,
|
||||
}
|
||||
83
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/control.go
generated
vendored
83
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/control.go
generated
vendored
@@ -1,83 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
errMissingAddress = errors.New("missing address")
|
||||
errInvalidConnType = errors.New("invalid conn type")
|
||||
errNoSuchInterface = errors.New("no such interface")
|
||||
)
|
||||
|
||||
// References:
|
||||
//
|
||||
// RFC 2292 Advanced Sockets API for IPv6
|
||||
// http://tools.ietf.org/html/rfc2292
|
||||
// RFC 2460 Internet Protocol, Version 6 (IPv6) Specification
|
||||
// http://tools.ietf.org/html/rfc2460
|
||||
// RFC 3493 Basic Socket Interface Extensions for IPv6
|
||||
// http://tools.ietf.org/html/rfc3493.html
|
||||
// RFC 3542 Advanced Sockets Application Program Interface (API) for IPv6
|
||||
// http://tools.ietf.org/html/rfc3542
|
||||
//
|
||||
// Note that RFC 3542 obsoltes RFC 2292 but OS X Snow Leopard and the
|
||||
// former still support RFC 2292 only. Please be aware that almost
|
||||
// all protocol implementations prohibit using a combination of RFC
|
||||
// 2292 and RFC 3542 for some practical reasons.
|
||||
|
||||
type rawOpt struct {
|
||||
sync.Mutex
|
||||
cflags ControlFlags
|
||||
}
|
||||
|
||||
func (c *rawOpt) set(f ControlFlags) { c.cflags |= f }
|
||||
func (c *rawOpt) clear(f ControlFlags) { c.cflags &^= f }
|
||||
func (c *rawOpt) isset(f ControlFlags) bool { return c.cflags&f != 0 }
|
||||
|
||||
// A ControlFlags reprensents per packet basis IP-level socket option
|
||||
// control flags.
|
||||
type ControlFlags uint
|
||||
|
||||
const (
|
||||
FlagTrafficClass ControlFlags = 1 << iota // pass the traffic class on the received packet
|
||||
FlagHopLimit // pass the hop limit on the received packet
|
||||
FlagSrc // pass the source address on the received packet
|
||||
FlagDst // pass the destination address on the received packet
|
||||
FlagInterface // pass the interface index on the received packet
|
||||
FlagPathMTU // pass the path MTU on the received packet path
|
||||
)
|
||||
|
||||
// A ControlMessage represents per packet basis IP-level socket
|
||||
// options.
|
||||
type ControlMessage struct {
|
||||
// Receiving socket options: SetControlMessage allows to
|
||||
// receive the options from the protocol stack using ReadFrom
|
||||
// method of PacketConn.
|
||||
//
|
||||
// Specifying socket options: ControlMessage for WriteTo
|
||||
// method of PacketConn allows to send the options to the
|
||||
// protocol stack.
|
||||
//
|
||||
TrafficClass int // traffic class, must be 1 <= value <= 255 when specifying
|
||||
HopLimit int // hop limit, must be 1 <= value <= 255 when specifying
|
||||
Src net.IP // source address, specifying only
|
||||
Dst net.IP // destination address, receiving only
|
||||
IfIndex int // interface index, must be 1 <= value when specifying
|
||||
NextHop net.IP // next hop address, specifying only
|
||||
MTU int // path MTU, receiving only
|
||||
}
|
||||
|
||||
func (cm *ControlMessage) String() string {
|
||||
if cm == nil {
|
||||
return "<nil>"
|
||||
}
|
||||
return fmt.Sprintf("tclass: %#x, hoplim: %v, src: %v, dst: %v, ifindex: %v, nexthop: %v, mtu: %v", cm.TrafficClass, cm.HopLimit, cm.Src, cm.Dst, cm.IfIndex, cm.NextHop, cm.MTU)
|
||||
}
|
||||
151
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/control_rfc2292_unix.go
generated
vendored
151
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/control_rfc2292_unix.go
generated
vendored
@@ -1,151 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build darwin
|
||||
|
||||
package ipv6
|
||||
|
||||
import (
|
||||
"net"
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const pktinfo = FlagDst | FlagInterface
|
||||
|
||||
func setControlMessage(fd int, opt *rawOpt, cf ControlFlags, on bool) error {
|
||||
opt.Lock()
|
||||
defer opt.Unlock()
|
||||
if cf&FlagHopLimit != 0 {
|
||||
if err := setIPv6ReceiveHopLimit(fd, on); err != nil {
|
||||
return err
|
||||
}
|
||||
if on {
|
||||
opt.set(FlagHopLimit)
|
||||
} else {
|
||||
opt.clear(FlagHopLimit)
|
||||
}
|
||||
}
|
||||
if cf&pktinfo != 0 {
|
||||
if err := setIPv6ReceivePacketInfo(fd, on); err != nil {
|
||||
return err
|
||||
}
|
||||
if on {
|
||||
opt.set(cf & pktinfo)
|
||||
} else {
|
||||
opt.clear(cf & pktinfo)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func newControlMessage(opt *rawOpt) (oob []byte) {
|
||||
opt.Lock()
|
||||
defer opt.Unlock()
|
||||
l, off := 0, 0
|
||||
if opt.isset(FlagHopLimit) {
|
||||
l += syscall.CmsgSpace(4)
|
||||
}
|
||||
if opt.isset(pktinfo) {
|
||||
l += syscall.CmsgSpace(sysSizeofPacketInfo)
|
||||
}
|
||||
if l > 0 {
|
||||
oob = make([]byte, l)
|
||||
if opt.isset(FlagHopLimit) {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIPv6
|
||||
m.Type = sysSockopt2292HopLimit
|
||||
m.SetLen(syscall.CmsgLen(4))
|
||||
off += syscall.CmsgSpace(4)
|
||||
}
|
||||
if opt.isset(pktinfo) {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIPv6
|
||||
m.Type = sysSockopt2292PacketInfo
|
||||
m.SetLen(syscall.CmsgLen(sysSizeofPacketInfo))
|
||||
off += syscall.CmsgSpace(sysSizeofPacketInfo)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func parseControlMessage(b []byte) (*ControlMessage, error) {
|
||||
if len(b) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
cmsgs, err := syscall.ParseSocketControlMessage(b)
|
||||
if err != nil {
|
||||
return nil, os.NewSyscallError("parse socket control message", err)
|
||||
}
|
||||
cm := &ControlMessage{}
|
||||
for _, m := range cmsgs {
|
||||
if m.Header.Level != ianaProtocolIPv6 {
|
||||
continue
|
||||
}
|
||||
switch m.Header.Type {
|
||||
case sysSockopt2292HopLimit:
|
||||
cm.HopLimit = int(*(*byte)(unsafe.Pointer(&m.Data[:1][0])))
|
||||
case sysSockopt2292PacketInfo:
|
||||
pi := (*sysPacketInfo)(unsafe.Pointer(&m.Data[0]))
|
||||
cm.IfIndex = int(pi.IfIndex)
|
||||
cm.Dst = pi.IP[:]
|
||||
}
|
||||
}
|
||||
return cm, nil
|
||||
}
|
||||
|
||||
func marshalControlMessage(cm *ControlMessage) (oob []byte) {
|
||||
if cm == nil {
|
||||
return
|
||||
}
|
||||
l, off := 0, 0
|
||||
if cm.HopLimit > 0 {
|
||||
l += syscall.CmsgSpace(4)
|
||||
}
|
||||
pion := false
|
||||
if cm.Src.To4() == nil && cm.Src.To16() != nil || cm.IfIndex != 0 {
|
||||
pion = true
|
||||
l += syscall.CmsgSpace(sysSizeofPacketInfo)
|
||||
}
|
||||
if len(cm.NextHop) == net.IPv6len {
|
||||
l += syscall.CmsgSpace(syscall.SizeofSockaddrInet6)
|
||||
}
|
||||
if l > 0 {
|
||||
oob = make([]byte, l)
|
||||
if cm.HopLimit > 0 {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIPv6
|
||||
m.Type = sysSockopt2292HopLimit
|
||||
m.SetLen(syscall.CmsgLen(4))
|
||||
data := oob[off+syscall.CmsgLen(0):]
|
||||
*(*byte)(unsafe.Pointer(&data[:1][0])) = byte(cm.HopLimit)
|
||||
off += syscall.CmsgSpace(4)
|
||||
}
|
||||
if pion {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIPv6
|
||||
m.Type = sysSockopt2292PacketInfo
|
||||
m.SetLen(syscall.CmsgLen(sysSizeofPacketInfo))
|
||||
pi := (*sysPacketInfo)(unsafe.Pointer(&oob[off+syscall.CmsgLen(0)]))
|
||||
if ip := cm.Src.To16(); ip != nil && ip.To4() == nil {
|
||||
copy(pi.IP[:], ip)
|
||||
}
|
||||
if cm.IfIndex != 0 {
|
||||
pi.IfIndex = uint32(cm.IfIndex)
|
||||
}
|
||||
off += syscall.CmsgSpace(sysSizeofPacketInfo)
|
||||
}
|
||||
if len(cm.NextHop) == net.IPv6len {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIPv6
|
||||
m.Type = sysSockopt2292NextHop
|
||||
m.SetLen(syscall.CmsgLen(syscall.SizeofSockaddrInet6))
|
||||
sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(&oob[off+syscall.CmsgLen(0)]))
|
||||
setSockaddr(sa, cm.NextHop, cm.IfIndex)
|
||||
off += syscall.CmsgSpace(syscall.SizeofSockaddrInet6)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
27
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/control_rfc3542_stub.go
generated
vendored
27
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/control_rfc3542_stub.go
generated
vendored
@@ -1,27 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build dragonfly plan9 solaris
|
||||
|
||||
package ipv6
|
||||
|
||||
func setControlMessage(fd int, opt *rawOpt, cf ControlFlags, on bool) error {
|
||||
// TODO(mikio): Implement this
|
||||
return errOpNoSupport
|
||||
}
|
||||
|
||||
func newControlMessage(opt *rawOpt) (oob []byte) {
|
||||
// TODO(mikio): Implement this
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseControlMessage(b []byte) (*ControlMessage, error) {
|
||||
// TODO(mikio): Implement this
|
||||
return nil, errOpNoSupport
|
||||
}
|
||||
|
||||
func marshalControlMessage(cm *ControlMessage) (oob []byte) {
|
||||
// TODO(mikio): Implement this
|
||||
return nil
|
||||
}
|
||||
210
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/control_rfc3542_unix.go
generated
vendored
210
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/control_rfc3542_unix.go
generated
vendored
@@ -1,210 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build freebsd linux netbsd openbsd
|
||||
|
||||
package ipv6
|
||||
|
||||
import (
|
||||
"net"
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const pktinfo = FlagDst | FlagInterface
|
||||
|
||||
func setControlMessage(fd int, opt *rawOpt, cf ControlFlags, on bool) error {
|
||||
opt.Lock()
|
||||
defer opt.Unlock()
|
||||
if cf&FlagTrafficClass != 0 {
|
||||
if err := setIPv6ReceiveTrafficClass(fd, on); err != nil {
|
||||
return err
|
||||
}
|
||||
if on {
|
||||
opt.set(FlagTrafficClass)
|
||||
} else {
|
||||
opt.clear(FlagTrafficClass)
|
||||
}
|
||||
}
|
||||
if cf&FlagHopLimit != 0 {
|
||||
if err := setIPv6ReceiveHopLimit(fd, on); err != nil {
|
||||
return err
|
||||
}
|
||||
if on {
|
||||
opt.set(FlagHopLimit)
|
||||
} else {
|
||||
opt.clear(FlagHopLimit)
|
||||
}
|
||||
}
|
||||
if cf&pktinfo != 0 {
|
||||
if err := setIPv6ReceivePacketInfo(fd, on); err != nil {
|
||||
return err
|
||||
}
|
||||
if on {
|
||||
opt.set(cf & pktinfo)
|
||||
} else {
|
||||
opt.clear(cf & pktinfo)
|
||||
}
|
||||
}
|
||||
if cf&FlagPathMTU != 0 {
|
||||
if err := setIPv6ReceivePathMTU(fd, on); err != nil {
|
||||
return err
|
||||
}
|
||||
if on {
|
||||
opt.set(FlagPathMTU)
|
||||
} else {
|
||||
opt.clear(FlagPathMTU)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func newControlMessage(opt *rawOpt) (oob []byte) {
|
||||
opt.Lock()
|
||||
defer opt.Unlock()
|
||||
l, off := 0, 0
|
||||
if opt.isset(FlagTrafficClass) {
|
||||
l += syscall.CmsgSpace(4)
|
||||
}
|
||||
if opt.isset(FlagHopLimit) {
|
||||
l += syscall.CmsgSpace(4)
|
||||
}
|
||||
if opt.isset(pktinfo) {
|
||||
l += syscall.CmsgSpace(sysSizeofPacketInfo)
|
||||
}
|
||||
if opt.isset(FlagPathMTU) {
|
||||
l += syscall.CmsgSpace(sysSizeofMTUInfo)
|
||||
}
|
||||
if l > 0 {
|
||||
oob = make([]byte, l)
|
||||
if opt.isset(FlagTrafficClass) {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIPv6
|
||||
m.Type = sysSockoptReceiveTrafficClass
|
||||
m.SetLen(syscall.CmsgLen(4))
|
||||
off += syscall.CmsgSpace(4)
|
||||
}
|
||||
if opt.isset(FlagHopLimit) {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIPv6
|
||||
m.Type = sysSockoptReceiveHopLimit
|
||||
m.SetLen(syscall.CmsgLen(4))
|
||||
off += syscall.CmsgSpace(4)
|
||||
}
|
||||
if opt.isset(pktinfo) {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIPv6
|
||||
m.Type = sysSockoptReceivePacketInfo
|
||||
m.SetLen(syscall.CmsgLen(sysSizeofPacketInfo))
|
||||
off += syscall.CmsgSpace(sysSizeofPacketInfo)
|
||||
}
|
||||
if opt.isset(FlagPathMTU) {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIPv6
|
||||
m.Type = sysSockoptReceivePathMTU
|
||||
m.SetLen(syscall.CmsgLen(sysSizeofMTUInfo))
|
||||
off += syscall.CmsgSpace(sysSizeofMTUInfo)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func parseControlMessage(b []byte) (*ControlMessage, error) {
|
||||
if len(b) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
cmsgs, err := syscall.ParseSocketControlMessage(b)
|
||||
if err != nil {
|
||||
return nil, os.NewSyscallError("parse socket control message", err)
|
||||
}
|
||||
cm := &ControlMessage{}
|
||||
for _, m := range cmsgs {
|
||||
if m.Header.Level != ianaProtocolIPv6 {
|
||||
continue
|
||||
}
|
||||
switch m.Header.Type {
|
||||
case sysSockoptTrafficClass:
|
||||
cm.TrafficClass = int(*(*byte)(unsafe.Pointer(&m.Data[:1][0])))
|
||||
case sysSockoptHopLimit:
|
||||
cm.HopLimit = int(*(*byte)(unsafe.Pointer(&m.Data[:1][0])))
|
||||
case sysSockoptPacketInfo:
|
||||
pi := (*sysPacketInfo)(unsafe.Pointer(&m.Data[0]))
|
||||
cm.Dst = pi.IP[:]
|
||||
cm.IfIndex = int(pi.IfIndex)
|
||||
case sysSockoptPathMTU:
|
||||
mi := (*sysMTUInfo)(unsafe.Pointer(&m.Data[0]))
|
||||
cm.Dst = mi.Addr.Addr[:]
|
||||
cm.IfIndex = int(mi.Addr.Scope_id)
|
||||
cm.MTU = int(mi.MTU)
|
||||
}
|
||||
}
|
||||
return cm, nil
|
||||
}
|
||||
|
||||
func marshalControlMessage(cm *ControlMessage) (oob []byte) {
|
||||
if cm == nil {
|
||||
return
|
||||
}
|
||||
l, off := 0, 0
|
||||
if cm.TrafficClass > 0 {
|
||||
l += syscall.CmsgSpace(4)
|
||||
}
|
||||
if cm.HopLimit > 0 {
|
||||
l += syscall.CmsgSpace(4)
|
||||
}
|
||||
pion := false
|
||||
if cm.Src.To4() == nil && cm.Src.To16() != nil || cm.IfIndex != 0 {
|
||||
pion = true
|
||||
l += syscall.CmsgSpace(sysSizeofPacketInfo)
|
||||
}
|
||||
if len(cm.NextHop) == net.IPv6len {
|
||||
l += syscall.CmsgSpace(syscall.SizeofSockaddrInet6)
|
||||
}
|
||||
if l > 0 {
|
||||
oob = make([]byte, l)
|
||||
if cm.TrafficClass > 0 {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIPv6
|
||||
m.Type = sysSockoptTrafficClass
|
||||
m.SetLen(syscall.CmsgLen(4))
|
||||
data := oob[off+syscall.CmsgLen(0):]
|
||||
*(*byte)(unsafe.Pointer(&data[:1][0])) = byte(cm.TrafficClass)
|
||||
off += syscall.CmsgSpace(4)
|
||||
}
|
||||
if cm.HopLimit > 0 {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIPv6
|
||||
m.Type = sysSockoptHopLimit
|
||||
m.SetLen(syscall.CmsgLen(4))
|
||||
data := oob[off+syscall.CmsgLen(0):]
|
||||
*(*byte)(unsafe.Pointer(&data[:1][0])) = byte(cm.HopLimit)
|
||||
off += syscall.CmsgSpace(4)
|
||||
}
|
||||
if pion {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIPv6
|
||||
m.Type = sysSockoptPacketInfo
|
||||
m.SetLen(syscall.CmsgLen(sysSizeofPacketInfo))
|
||||
pi := (*sysPacketInfo)(unsafe.Pointer(&oob[off+syscall.CmsgLen(0)]))
|
||||
if ip := cm.Src.To16(); ip != nil && ip.To4() == nil {
|
||||
copy(pi.IP[:], ip)
|
||||
}
|
||||
if cm.IfIndex != 0 {
|
||||
pi.IfIndex = uint32(cm.IfIndex)
|
||||
}
|
||||
off += syscall.CmsgSpace(sysSizeofPacketInfo)
|
||||
}
|
||||
if len(cm.NextHop) == net.IPv6len {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIPv6
|
||||
m.Type = sysSockoptNextHop
|
||||
m.SetLen(syscall.CmsgLen(syscall.SizeofSockaddrInet6))
|
||||
sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(&oob[off+syscall.CmsgLen(0)]))
|
||||
setSockaddr(sa, cm.NextHop, cm.IfIndex)
|
||||
off += syscall.CmsgSpace(syscall.SizeofSockaddrInet6)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
27
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/control_rfc3542_windows.go
generated
vendored
27
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/control_rfc3542_windows.go
generated
vendored
@@ -1,27 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6
|
||||
|
||||
import "syscall"
|
||||
|
||||
func setControlMessage(fd syscall.Handle, opt *rawOpt, cf ControlFlags, on bool) error {
|
||||
// TODO(mikio): Implement this
|
||||
return syscall.EWINDOWS
|
||||
}
|
||||
|
||||
func newControlMessage(opt *rawOpt) (oob []byte) {
|
||||
// TODO(mikio): Implement this
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseControlMessage(b []byte) (*ControlMessage, error) {
|
||||
// TODO(mikio): Implement this
|
||||
return nil, syscall.EWINDOWS
|
||||
}
|
||||
|
||||
func marshalControlMessage(cm *ControlMessage) (oob []byte) {
|
||||
// TODO(mikio): Implement this
|
||||
return nil
|
||||
}
|
||||
178
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/dgramopt_posix.go
generated
vendored
178
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/dgramopt_posix.go
generated
vendored
@@ -1,178 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build darwin freebsd linux netbsd openbsd windows
|
||||
|
||||
package ipv6
|
||||
|
||||
import (
|
||||
"net"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// MulticastHopLimit returns the hop limit field value for outgoing
|
||||
// multicast packets.
|
||||
func (c *dgramOpt) MulticastHopLimit() (int, error) {
|
||||
if !c.ok() {
|
||||
return 0, syscall.EINVAL
|
||||
}
|
||||
fd, err := c.sysfd()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return ipv6MulticastHopLimit(fd)
|
||||
}
|
||||
|
||||
// SetMulticastHopLimit sets the hop limit field value for future
|
||||
// outgoing multicast packets.
|
||||
func (c *dgramOpt) SetMulticastHopLimit(hoplim int) error {
|
||||
if !c.ok() {
|
||||
return syscall.EINVAL
|
||||
}
|
||||
fd, err := c.sysfd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return setIPv6MulticastHopLimit(fd, hoplim)
|
||||
}
|
||||
|
||||
// MulticastInterface returns the default interface for multicast
|
||||
// packet transmissions.
|
||||
func (c *dgramOpt) MulticastInterface() (*net.Interface, error) {
|
||||
if !c.ok() {
|
||||
return nil, syscall.EINVAL
|
||||
}
|
||||
fd, err := c.sysfd()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ipv6MulticastInterface(fd)
|
||||
}
|
||||
|
||||
// SetMulticastInterface sets the default interface for future
|
||||
// multicast packet transmissions.
|
||||
func (c *dgramOpt) SetMulticastInterface(ifi *net.Interface) error {
|
||||
if !c.ok() {
|
||||
return syscall.EINVAL
|
||||
}
|
||||
fd, err := c.sysfd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return setIPv6MulticastInterface(fd, ifi)
|
||||
}
|
||||
|
||||
// MulticastLoopback reports whether transmitted multicast packets
|
||||
// should be copied and send back to the originator.
|
||||
func (c *dgramOpt) MulticastLoopback() (bool, error) {
|
||||
if !c.ok() {
|
||||
return false, syscall.EINVAL
|
||||
}
|
||||
fd, err := c.sysfd()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return ipv6MulticastLoopback(fd)
|
||||
}
|
||||
|
||||
// SetMulticastLoopback sets whether transmitted multicast packets
|
||||
// should be copied and send back to the originator.
|
||||
func (c *dgramOpt) SetMulticastLoopback(on bool) error {
|
||||
if !c.ok() {
|
||||
return syscall.EINVAL
|
||||
}
|
||||
fd, err := c.sysfd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return setIPv6MulticastLoopback(fd, on)
|
||||
}
|
||||
|
||||
// JoinGroup joins the group address group on the interface ifi.
|
||||
// It uses the system assigned multicast interface when ifi is nil,
|
||||
// although this is not recommended because the assignment depends on
|
||||
// platforms and sometimes it might require routing configuration.
|
||||
func (c *dgramOpt) JoinGroup(ifi *net.Interface, group net.Addr) error {
|
||||
if !c.ok() {
|
||||
return syscall.EINVAL
|
||||
}
|
||||
fd, err := c.sysfd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
grp := netAddrToIP16(group)
|
||||
if grp == nil {
|
||||
return errMissingAddress
|
||||
}
|
||||
return joinIPv6Group(fd, ifi, grp)
|
||||
}
|
||||
|
||||
// LeaveGroup leaves the group address group on the interface ifi.
|
||||
func (c *dgramOpt) LeaveGroup(ifi *net.Interface, group net.Addr) error {
|
||||
if !c.ok() {
|
||||
return syscall.EINVAL
|
||||
}
|
||||
fd, err := c.sysfd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
grp := netAddrToIP16(group)
|
||||
if grp == nil {
|
||||
return errMissingAddress
|
||||
}
|
||||
return leaveIPv6Group(fd, ifi, grp)
|
||||
}
|
||||
|
||||
// Checksum reports whether the kernel will compute, store or verify a
|
||||
// checksum for both incoming and outgoing packets. If on is true, it
|
||||
// returns an offset in bytes into the data of where the checksum
|
||||
// field is located.
|
||||
func (c *dgramOpt) Checksum() (on bool, offset int, err error) {
|
||||
if !c.ok() {
|
||||
return false, 0, syscall.EINVAL
|
||||
}
|
||||
fd, err := c.sysfd()
|
||||
if err != nil {
|
||||
return false, 0, err
|
||||
}
|
||||
return ipv6Checksum(fd)
|
||||
}
|
||||
|
||||
// SetChecksum enables the kernel checksum processing. If on is ture,
|
||||
// the offset should be an offset in bytes into the data of where the
|
||||
// checksum field is located.
|
||||
func (c *dgramOpt) SetChecksum(on bool, offset int) error {
|
||||
if !c.ok() {
|
||||
return syscall.EINVAL
|
||||
}
|
||||
fd, err := c.sysfd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return setIPv6Checksum(fd, on, offset)
|
||||
}
|
||||
|
||||
// ICMPFilter returns an ICMP filter.
|
||||
func (c *dgramOpt) ICMPFilter() (*ICMPFilter, error) {
|
||||
if !c.ok() {
|
||||
return nil, syscall.EINVAL
|
||||
}
|
||||
fd, err := c.sysfd()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ipv6ICMPFilter(fd)
|
||||
}
|
||||
|
||||
// SetICMPFilter deploys the ICMP filter.
|
||||
func (c *dgramOpt) SetICMPFilter(f *ICMPFilter) error {
|
||||
if !c.ok() {
|
||||
return syscall.EINVAL
|
||||
}
|
||||
fd, err := c.sysfd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return setIPv6ICMPFilter(fd, f)
|
||||
}
|
||||
95
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/dgramopt_stub.go
generated
vendored
95
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/dgramopt_stub.go
generated
vendored
@@ -1,95 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build dragonfly plan9 solaris
|
||||
|
||||
package ipv6
|
||||
|
||||
import "net"
|
||||
|
||||
// MulticastHopLimit returns the hop limit field value for outgoing
|
||||
// multicast packets.
|
||||
func (c *dgramOpt) MulticastHopLimit() (int, error) {
|
||||
// TODO(mikio): Implement this
|
||||
return 0, errOpNoSupport
|
||||
}
|
||||
|
||||
// SetMulticastHopLimit sets the hop limit field value for future
|
||||
// outgoing multicast packets.
|
||||
func (c *dgramOpt) SetMulticastHopLimit(hoplim int) error {
|
||||
// TODO(mikio): Implement this
|
||||
return errOpNoSupport
|
||||
}
|
||||
|
||||
// MulticastInterface returns the default interface for multicast
|
||||
// packet transmissions.
|
||||
func (c *dgramOpt) MulticastInterface() (*net.Interface, error) {
|
||||
// TODO(mikio): Implement this
|
||||
return nil, errOpNoSupport
|
||||
}
|
||||
|
||||
// SetMulticastInterface sets the default interface for future
|
||||
// multicast packet transmissions.
|
||||
func (c *dgramOpt) SetMulticastInterface(ifi *net.Interface) error {
|
||||
// TODO(mikio): Implement this
|
||||
return errOpNoSupport
|
||||
}
|
||||
|
||||
// MulticastLoopback reports whether transmitted multicast packets
|
||||
// should be copied and send back to the originator.
|
||||
func (c *dgramOpt) MulticastLoopback() (bool, error) {
|
||||
// TODO(mikio): Implement this
|
||||
return false, errOpNoSupport
|
||||
}
|
||||
|
||||
// SetMulticastLoopback sets whether transmitted multicast packets
|
||||
// should be copied and send back to the originator.
|
||||
func (c *dgramOpt) SetMulticastLoopback(on bool) error {
|
||||
// TODO(mikio): Implement this
|
||||
return errOpNoSupport
|
||||
}
|
||||
|
||||
// JoinGroup joins the group address group on the interface ifi.
|
||||
// It uses the system assigned multicast interface when ifi is nil,
|
||||
// although this is not recommended because the assignment depends on
|
||||
// platforms and sometimes it might require routing configuration.
|
||||
func (c *dgramOpt) JoinGroup(ifi *net.Interface, group net.Addr) error {
|
||||
// TODO(mikio): Implement this
|
||||
return errOpNoSupport
|
||||
}
|
||||
|
||||
// LeaveGroup leaves the group address group on the interface ifi.
|
||||
func (c *dgramOpt) LeaveGroup(ifi *net.Interface, group net.Addr) error {
|
||||
// TODO(mikio): Implement this
|
||||
return errOpNoSupport
|
||||
}
|
||||
|
||||
// Checksum reports whether the kernel will compute, store or verify a
|
||||
// checksum for both incoming and outgoing packets. If on is true, it
|
||||
// returns an offset in bytes into the data of where the checksum
|
||||
// field is located.
|
||||
func (c *dgramOpt) Checksum() (on bool, offset int, err error) {
|
||||
// TODO(mikio): Implement this
|
||||
return false, 0, errOpNoSupport
|
||||
}
|
||||
|
||||
// SetChecksum enables the kernel checksum processing. If on is ture,
|
||||
// the offset should be an offset in bytes into the data of where the
|
||||
// checksum field is located.
|
||||
func (c *dgramOpt) SetChecksum(on bool, offset int) error {
|
||||
// TODO(mikio): Implement this
|
||||
return errOpNoSupport
|
||||
}
|
||||
|
||||
// ICMPFilter returns an ICMP filter.
|
||||
func (c *dgramOpt) ICMPFilter() (*ICMPFilter, error) {
|
||||
// TODO(mikio): Implement this
|
||||
return nil, errOpNoSupport
|
||||
}
|
||||
|
||||
// SetICMPFilter deploys the ICMP filter.
|
||||
func (c *dgramOpt) SetICMPFilter(f *ICMPFilter) error {
|
||||
// TODO(mikio): Implement this
|
||||
return errOpNoSupport
|
||||
}
|
||||
193
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/doc.go
generated
vendored
193
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/doc.go
generated
vendored
@@ -1,193 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package ipv6 implements IP-level socket options for the Internet
|
||||
// Protocol version 6.
|
||||
//
|
||||
// The package provides IP-level socket options that allow
|
||||
// manipulation of IPv6 facilities. The IPv6 and socket options for
|
||||
// IPv6 are defined in RFC 2460, RFC 3493 and RFC 3542.
|
||||
//
|
||||
//
|
||||
// Unicasting
|
||||
//
|
||||
// The options for unicasting are available for net.TCPConn,
|
||||
// net.UDPConn and net.IPConn which are created as network connections
|
||||
// that use the IPv6 transport. When a single TCP connection carrying
|
||||
// a data flow of multiple packets needs to indicate the flow is
|
||||
// important, ipv6.Conn is used to set the traffic class field on the
|
||||
// IPv6 header for each packet.
|
||||
//
|
||||
// ln, err := net.Listen("tcp6", "[::]:1024")
|
||||
// if err != nil {
|
||||
// // error handling
|
||||
// }
|
||||
// defer ln.Close()
|
||||
// for {
|
||||
// c, err := ln.Accept()
|
||||
// if err != nil {
|
||||
// // error handling
|
||||
// }
|
||||
// go func(c net.Conn) {
|
||||
// defer c.Close()
|
||||
//
|
||||
// The outgoing packets will be labeled DiffServ assured forwarding
|
||||
// class 1 low drop precedence, as known as AF11 packets.
|
||||
//
|
||||
// if err := ipv6.NewConn(c).SetTrafficClass(DiffServAF11); err != nil {
|
||||
// // error handling
|
||||
// }
|
||||
// if _, err := c.Write(data); err != nil {
|
||||
// // error handling
|
||||
// }
|
||||
// }(c)
|
||||
// }
|
||||
//
|
||||
//
|
||||
// Multicasting
|
||||
//
|
||||
// The options for multicasting are available for net.UDPConn and
|
||||
// net.IPconn which are created as network connections that use the
|
||||
// IPv6 transport. A few network facilities must be prepared before
|
||||
// you begin multicasting, at a minimum joining network interfaces and
|
||||
// multicast groups.
|
||||
//
|
||||
// en0, err := net.InterfaceByName("en0")
|
||||
// if err != nil {
|
||||
// // error handling
|
||||
// }
|
||||
// en1, err := net.InterfaceByIndex(911)
|
||||
// if err != nil {
|
||||
// // error handling
|
||||
// }
|
||||
// group := net.ParseIP("ff02::114")
|
||||
//
|
||||
// First, an application listens to an appropriate address with an
|
||||
// appropriate service port.
|
||||
//
|
||||
// c, err := net.ListenPacket("udp6", "[::]:1024")
|
||||
// if err != nil {
|
||||
// // error handling
|
||||
// }
|
||||
// defer c.Close()
|
||||
//
|
||||
// Second, the application joins multicast groups, starts listening to
|
||||
// the groups on the specified network interfaces. Note that the
|
||||
// service port for transport layer protocol does not matter with this
|
||||
// operation as joining groups affects only network and link layer
|
||||
// protocols, such as IPv6 and Ethernet.
|
||||
//
|
||||
// p := ipv6.NewPacketConn(c)
|
||||
// if err := p.JoinGroup(en0, &net.UDPAddr{IP: group}); err != nil {
|
||||
// // error handling
|
||||
// }
|
||||
// if err := p.JoinGroup(en1, &net.UDPAddr{IP: group}); err != nil {
|
||||
// // error handling
|
||||
// }
|
||||
//
|
||||
// The application might set per packet control message transmissions
|
||||
// between the protocol stack within the kernel. When the application
|
||||
// needs a destination address on an incoming packet,
|
||||
// SetControlMessage of ipv6.PacketConn is used to enable control
|
||||
// message transmissons.
|
||||
//
|
||||
// if err := p.SetControlMessage(ipv6.FlagDst, true); err != nil {
|
||||
// // error handling
|
||||
// }
|
||||
//
|
||||
// The application could identify whether the received packets are
|
||||
// of interest by using the control message that contains the
|
||||
// destination address of the received packet.
|
||||
//
|
||||
// b := make([]byte, 1500)
|
||||
// for {
|
||||
// n, rcm, src, err := p.ReadFrom(b)
|
||||
// if err != nil {
|
||||
// // error handling
|
||||
// }
|
||||
// if rcm.Dst.IsMulticast() {
|
||||
// if rcm.Dst.Equal(group)
|
||||
// // joined group, do something
|
||||
// } else {
|
||||
// // unknown group, discard
|
||||
// continue
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// The application can also send both unicast and multicast packets.
|
||||
//
|
||||
// p.SetTrafficClass(DiffServCS0)
|
||||
// p.SetHopLimit(16)
|
||||
// if _, err := p.WriteTo(data[:n], nil, src); err != nil {
|
||||
// // error handling
|
||||
// }
|
||||
// dst := &net.UDPAddr{IP: group, Port: 1024}
|
||||
// wcm := ipv6.ControlMessage{TrafficClass: DiffServCS7, HopLimit: 1}
|
||||
// for _, ifi := range []*net.Interface{en0, en1} {
|
||||
// wcm.IfIndex = ifi.Index
|
||||
// if _, err := p.WriteTo(data[:n], &wcm, dst); err != nil {
|
||||
// // error handling
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
// More multicasting
|
||||
//
|
||||
// An application that uses PacketConn may join multiple multicast
|
||||
// groups. For example, a UDP listener with port 1024 might join two
|
||||
// different groups across over two different network interfaces by
|
||||
// using:
|
||||
//
|
||||
// c, err := net.ListenPacket("udp6", "[::]:1024")
|
||||
// if err != nil {
|
||||
// // error handling
|
||||
// }
|
||||
// defer c.Close()
|
||||
// p := ipv6.NewPacketConn(c)
|
||||
// if err := p.JoinGroup(en0, &net.UDPAddr{IP: net.ParseIP("ff02::1:114")}); err != nil {
|
||||
// // error handling
|
||||
// }
|
||||
// if err := p.JoinGroup(en0, &net.UDPAddr{IP: net.ParseIP("ff02::2:114")}); err != nil {
|
||||
// // error handling
|
||||
// }
|
||||
// if err := p.JoinGroup(en1, &net.UDPAddr{IP: net.ParseIP("ff02::2:114")}); err != nil {
|
||||
// // error handling
|
||||
// }
|
||||
//
|
||||
// It is possible for multiple UDP listeners that listen on the same
|
||||
// UDP port to join the same multicast group. The net package will
|
||||
// provide a socket that listens to a wildcard address with reusable
|
||||
// UDP port when an appropriate multicast address prefix is passed to
|
||||
// the net.ListenPacket or net.ListenUDP.
|
||||
//
|
||||
// c1, err := net.ListenPacket("udp6", "[ff02::]:1024")
|
||||
// if err != nil {
|
||||
// // error handling
|
||||
// }
|
||||
// defer c1.Close()
|
||||
// c2, err := net.ListenPacket("udp6", "[ff02::]:1024")
|
||||
// if err != nil {
|
||||
// // error handling
|
||||
// }
|
||||
// defer c2.Close()
|
||||
// p1 := ipv6.NewPacketConn(c1)
|
||||
// if err := p1.JoinGroup(en0, &net.UDPAddr{IP: net.ParseIP("ff02::114")}); err != nil {
|
||||
// // error handling
|
||||
// }
|
||||
// p2 := ipv6.NewPacketConn(c2)
|
||||
// if err := p2.JoinGroup(en0, &net.UDPAddr{IP: net.ParseIP("ff02::114")}); err != nil {
|
||||
// // error handling
|
||||
// }
|
||||
//
|
||||
// Also it is possible for the application to leave or rejoin a
|
||||
// multicast group on the network interface.
|
||||
//
|
||||
// if err := p.LeaveGroup(en0, &net.UDPAddr{IP: net.ParseIP("ff02::114")}); err != nil {
|
||||
// // error handling
|
||||
// }
|
||||
// if err := p.JoinGroup(en0, &net.UDPAddr{IP: net.ParseIP("ff01::114")}); err != nil {
|
||||
// // error handling
|
||||
// }
|
||||
package ipv6
|
||||
119
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/endpoint.go
generated
vendored
119
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/endpoint.go
generated
vendored
@@ -1,119 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6
|
||||
|
||||
import (
|
||||
"net"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
// A Conn represents a network endpoint that uses IPv6 transport.
|
||||
// It allows to set basic IP-level socket options such as traffic
|
||||
// class and hop limit.
|
||||
type Conn struct {
|
||||
genericOpt
|
||||
}
|
||||
|
||||
type genericOpt struct {
|
||||
net.Conn
|
||||
}
|
||||
|
||||
func (c *genericOpt) ok() bool { return c != nil && c.Conn != nil }
|
||||
|
||||
// PathMTU returns a path MTU value for the destination associated
|
||||
// with the endpoint.
|
||||
func (c *Conn) PathMTU() (int, error) {
|
||||
if !c.genericOpt.ok() {
|
||||
return 0, syscall.EINVAL
|
||||
}
|
||||
fd, err := c.genericOpt.sysfd()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return ipv6PathMTU(fd)
|
||||
}
|
||||
|
||||
// NewConn returns a new Conn.
|
||||
func NewConn(c net.Conn) *Conn {
|
||||
return &Conn{
|
||||
genericOpt: genericOpt{Conn: c},
|
||||
}
|
||||
}
|
||||
|
||||
// A PacketConn represents a packet network endpoint that uses IPv6
|
||||
// transport. It is used to control several IP-level socket options
|
||||
// including IPv6 header manipulation. It also provides datagram
|
||||
// based network I/O methods specific to the IPv6 and higher layer
|
||||
// protocols such as OSPF, GRE, and UDP.
|
||||
type PacketConn struct {
|
||||
genericOpt
|
||||
dgramOpt
|
||||
payloadHandler
|
||||
}
|
||||
|
||||
type dgramOpt struct {
|
||||
net.PacketConn
|
||||
}
|
||||
|
||||
func (c *dgramOpt) ok() bool { return c != nil && c.PacketConn != nil }
|
||||
|
||||
// SetControlMessage allows to receive the per packet basis IP-level
|
||||
// socket options.
|
||||
func (c *PacketConn) SetControlMessage(cf ControlFlags, on bool) error {
|
||||
if !c.payloadHandler.ok() {
|
||||
return syscall.EINVAL
|
||||
}
|
||||
fd, err := c.payloadHandler.sysfd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return setControlMessage(fd, &c.payloadHandler.rawOpt, cf, on)
|
||||
}
|
||||
|
||||
// SetDeadline sets the read and write deadlines associated with the
|
||||
// endpoint.
|
||||
func (c *PacketConn) SetDeadline(t time.Time) error {
|
||||
if !c.payloadHandler.ok() {
|
||||
return syscall.EINVAL
|
||||
}
|
||||
return c.payloadHandler.SetDeadline(t)
|
||||
}
|
||||
|
||||
// SetReadDeadline sets the read deadline associated with the
|
||||
// endpoint.
|
||||
func (c *PacketConn) SetReadDeadline(t time.Time) error {
|
||||
if !c.payloadHandler.ok() {
|
||||
return syscall.EINVAL
|
||||
}
|
||||
return c.payloadHandler.SetReadDeadline(t)
|
||||
}
|
||||
|
||||
// SetWriteDeadline sets the write deadline associated with the
|
||||
// endpoint.
|
||||
func (c *PacketConn) SetWriteDeadline(t time.Time) error {
|
||||
if !c.payloadHandler.ok() {
|
||||
return syscall.EINVAL
|
||||
}
|
||||
return c.payloadHandler.SetWriteDeadline(t)
|
||||
}
|
||||
|
||||
// Close closes the endpoint.
|
||||
func (c *PacketConn) Close() error {
|
||||
if !c.payloadHandler.ok() {
|
||||
return syscall.EINVAL
|
||||
}
|
||||
return c.payloadHandler.Close()
|
||||
}
|
||||
|
||||
// NewPacketConn returns a new PacketConn using c as its underlying
|
||||
// transport.
|
||||
func NewPacketConn(c net.PacketConn) *PacketConn {
|
||||
return &PacketConn{
|
||||
genericOpt: genericOpt{Conn: c.(net.Conn)},
|
||||
dgramOpt: dgramOpt{PacketConn: c},
|
||||
payloadHandler: payloadHandler{PacketConn: c},
|
||||
}
|
||||
}
|
||||
241
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/gen.go
generated
vendored
241
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/gen.go
generated
vendored
@@ -1,241 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build ignore
|
||||
|
||||
// This program generates internet protocol constatns and tables by
|
||||
// reading IANA protocol registries.
|
||||
//
|
||||
// Usage:
|
||||
// go run gen.go > iana.go
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"go/format"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var registries = []struct {
|
||||
url string
|
||||
parse func(io.Writer, io.Reader) error
|
||||
}{
|
||||
{
|
||||
"http://www.iana.org/assignments/icmpv6-parameters/icmpv6-parameters.xml",
|
||||
parseICMPv6Parameters,
|
||||
},
|
||||
{
|
||||
"http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xml",
|
||||
parseProtocolNumbers,
|
||||
},
|
||||
}
|
||||
|
||||
func main() {
|
||||
var bb bytes.Buffer
|
||||
fmt.Fprintf(&bb, "// go run gen.go\n")
|
||||
fmt.Fprintf(&bb, "// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT\n\n")
|
||||
fmt.Fprintf(&bb, "package ipv6\n\n")
|
||||
for _, r := range registries {
|
||||
resp, err := http.Get(r.url)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
fmt.Fprintf(os.Stderr, "got HTTP status code %v for %v\n", resp.StatusCode, r.url)
|
||||
os.Exit(1)
|
||||
}
|
||||
if err := r.parse(&bb, resp.Body); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Fprintf(&bb, "\n")
|
||||
}
|
||||
b, err := format.Source(bb.Bytes())
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
os.Stdout.Write(b)
|
||||
}
|
||||
|
||||
func parseICMPv6Parameters(w io.Writer, r io.Reader) error {
|
||||
dec := xml.NewDecoder(r)
|
||||
var icp icmpv6Parameters
|
||||
if err := dec.Decode(&icp); err != nil {
|
||||
return err
|
||||
}
|
||||
prs := icp.escape()
|
||||
fmt.Fprintf(w, "// %s, Updated: %s\n", icp.Title, icp.Updated)
|
||||
fmt.Fprintf(w, "const (\n")
|
||||
for _, pr := range prs {
|
||||
if pr.Name == "" {
|
||||
continue
|
||||
}
|
||||
fmt.Fprintf(w, "ICMPType%s ICMPType = %d", pr.Name, pr.Value)
|
||||
fmt.Fprintf(w, "// %s\n", pr.OrigName)
|
||||
}
|
||||
fmt.Fprintf(w, ")\n\n")
|
||||
fmt.Fprintf(w, "// %s, Updated: %s\n", icp.Title, icp.Updated)
|
||||
fmt.Fprintf(w, "var icmpTypes = map[ICMPType]string{\n")
|
||||
for _, pr := range prs {
|
||||
if pr.Name == "" {
|
||||
continue
|
||||
}
|
||||
fmt.Fprintf(w, "%d: %q,\n", pr.Value, strings.ToLower(pr.OrigName))
|
||||
}
|
||||
fmt.Fprintf(w, "}\n")
|
||||
return nil
|
||||
}
|
||||
|
||||
type icmpv6Parameters struct {
|
||||
XMLName xml.Name `xml:"registry"`
|
||||
Title string `xml:"title"`
|
||||
Updated string `xml:"updated"`
|
||||
Registries []struct {
|
||||
Title string `xml:"title"`
|
||||
Records []struct {
|
||||
Value string `xml:"value"`
|
||||
Name string `xml:"name"`
|
||||
} `xml:"record"`
|
||||
} `xml:"registry"`
|
||||
}
|
||||
|
||||
type canonICMPv6ParamRecord struct {
|
||||
OrigName string
|
||||
Name string
|
||||
Value int
|
||||
}
|
||||
|
||||
func (icp *icmpv6Parameters) escape() []canonICMPv6ParamRecord {
|
||||
id := -1
|
||||
for i, r := range icp.Registries {
|
||||
if strings.Contains(r.Title, "Type") || strings.Contains(r.Title, "type") {
|
||||
id = i
|
||||
break
|
||||
}
|
||||
}
|
||||
if id < 0 {
|
||||
return nil
|
||||
}
|
||||
prs := make([]canonICMPv6ParamRecord, len(icp.Registries[id].Records))
|
||||
sr := strings.NewReplacer(
|
||||
"Messages", "",
|
||||
"Message", "",
|
||||
"ICMP", "",
|
||||
"+", "P",
|
||||
"-", "",
|
||||
"/", "",
|
||||
".", "",
|
||||
" ", "",
|
||||
)
|
||||
for i, pr := range icp.Registries[id].Records {
|
||||
if strings.Contains(pr.Name, "Reserved") ||
|
||||
strings.Contains(pr.Name, "Unassigned") ||
|
||||
strings.Contains(pr.Name, "Deprecated") ||
|
||||
strings.Contains(pr.Name, "Experiment") ||
|
||||
strings.Contains(pr.Name, "experiment") {
|
||||
continue
|
||||
}
|
||||
ss := strings.Split(pr.Name, "\n")
|
||||
if len(ss) > 1 {
|
||||
prs[i].Name = strings.Join(ss, " ")
|
||||
} else {
|
||||
prs[i].Name = ss[0]
|
||||
}
|
||||
s := strings.TrimSpace(prs[i].Name)
|
||||
prs[i].OrigName = s
|
||||
prs[i].Name = sr.Replace(s)
|
||||
prs[i].Value, _ = strconv.Atoi(pr.Value)
|
||||
}
|
||||
return prs
|
||||
}
|
||||
|
||||
func parseProtocolNumbers(w io.Writer, r io.Reader) error {
|
||||
dec := xml.NewDecoder(r)
|
||||
var pn protocolNumbers
|
||||
if err := dec.Decode(&pn); err != nil {
|
||||
return err
|
||||
}
|
||||
prs := pn.escape()
|
||||
fmt.Fprintf(w, "// %s, Updated: %s\n", pn.Title, pn.Updated)
|
||||
fmt.Fprintf(w, "const (\n")
|
||||
for _, pr := range prs {
|
||||
if pr.Name == "" {
|
||||
continue
|
||||
}
|
||||
fmt.Fprintf(w, "ianaProtocol%s = %d", pr.Name, pr.Value)
|
||||
s := pr.Descr
|
||||
if s == "" {
|
||||
s = pr.OrigName
|
||||
}
|
||||
fmt.Fprintf(w, "// %s\n", s)
|
||||
}
|
||||
fmt.Fprintf(w, ")\n")
|
||||
return nil
|
||||
}
|
||||
|
||||
type protocolNumbers struct {
|
||||
XMLName xml.Name `xml:"registry"`
|
||||
Title string `xml:"title"`
|
||||
Updated string `xml:"updated"`
|
||||
RegTitle string `xml:"registry>title"`
|
||||
Note string `xml:"registry>note"`
|
||||
Records []struct {
|
||||
Value string `xml:"value"`
|
||||
Name string `xml:"name"`
|
||||
Descr string `xml:"description"`
|
||||
} `xml:"registry>record"`
|
||||
}
|
||||
|
||||
type canonProtocolRecord struct {
|
||||
OrigName string
|
||||
Name string
|
||||
Descr string
|
||||
Value int
|
||||
}
|
||||
|
||||
func (pn *protocolNumbers) escape() []canonProtocolRecord {
|
||||
prs := make([]canonProtocolRecord, len(pn.Records))
|
||||
sr := strings.NewReplacer(
|
||||
"-in-", "in",
|
||||
"-within-", "within",
|
||||
"-over-", "over",
|
||||
"+", "P",
|
||||
"-", "",
|
||||
"/", "",
|
||||
".", "",
|
||||
" ", "",
|
||||
)
|
||||
for i, pr := range pn.Records {
|
||||
prs[i].OrigName = pr.Name
|
||||
s := strings.TrimSpace(pr.Name)
|
||||
switch pr.Name {
|
||||
case "ISIS over IPv4":
|
||||
prs[i].Name = "ISIS"
|
||||
case "manet":
|
||||
prs[i].Name = "MANET"
|
||||
default:
|
||||
prs[i].Name = sr.Replace(s)
|
||||
}
|
||||
ss := strings.Split(pr.Descr, "\n")
|
||||
for i := range ss {
|
||||
ss[i] = strings.TrimSpace(ss[i])
|
||||
}
|
||||
if len(ss) > 1 {
|
||||
prs[i].Descr = strings.Join(ss, " ")
|
||||
} else {
|
||||
prs[i].Descr = ss[0]
|
||||
}
|
||||
prs[i].Value, _ = strconv.Atoi(pr.Value)
|
||||
}
|
||||
return prs
|
||||
}
|
||||
60
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/genericopt_posix.go
generated
vendored
60
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/genericopt_posix.go
generated
vendored
@@ -1,60 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build darwin freebsd linux netbsd openbsd windows
|
||||
|
||||
package ipv6
|
||||
|
||||
import "syscall"
|
||||
|
||||
// TrafficClass returns the traffic class field value for outgoing
|
||||
// packets.
|
||||
func (c *genericOpt) TrafficClass() (int, error) {
|
||||
if !c.ok() {
|
||||
return 0, syscall.EINVAL
|
||||
}
|
||||
fd, err := c.sysfd()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return ipv6TrafficClass(fd)
|
||||
}
|
||||
|
||||
// SetTrafficClass sets the traffic class field value for future
|
||||
// outgoing packets.
|
||||
func (c *genericOpt) SetTrafficClass(tclass int) error {
|
||||
if !c.ok() {
|
||||
return syscall.EINVAL
|
||||
}
|
||||
fd, err := c.sysfd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return setIPv6TrafficClass(fd, tclass)
|
||||
}
|
||||
|
||||
// HopLimit returns the hop limit field value for outgoing packets.
|
||||
func (c *genericOpt) HopLimit() (int, error) {
|
||||
if !c.ok() {
|
||||
return 0, syscall.EINVAL
|
||||
}
|
||||
fd, err := c.sysfd()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return ipv6HopLimit(fd)
|
||||
}
|
||||
|
||||
// SetHopLimit sets the hop limit field value for future outgoing
|
||||
// packets.
|
||||
func (c *genericOpt) SetHopLimit(hoplim int) error {
|
||||
if !c.ok() {
|
||||
return syscall.EINVAL
|
||||
}
|
||||
fd, err := c.sysfd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return setIPv6HopLimit(fd, hoplim)
|
||||
}
|
||||
34
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/genericopt_stub.go
generated
vendored
34
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/genericopt_stub.go
generated
vendored
@@ -1,34 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build dragonfly plan9 solaris
|
||||
|
||||
package ipv6
|
||||
|
||||
// TrafficClass returns the traffic class field value for outgoing
|
||||
// packets.
|
||||
func (c *genericOpt) TrafficClass() (int, error) {
|
||||
// TODO(mikio): Implement this
|
||||
return 0, errOpNoSupport
|
||||
}
|
||||
|
||||
// SetTrafficClass sets the traffic class field value for future
|
||||
// outgoing packets.
|
||||
func (c *genericOpt) SetTrafficClass(tclass int) error {
|
||||
// TODO(mikio): Implement this
|
||||
return errOpNoSupport
|
||||
}
|
||||
|
||||
// HopLimit returns the hop limit field value for outgoing packets.
|
||||
func (c *genericOpt) HopLimit() (int, error) {
|
||||
// TODO(mikio): Implement this
|
||||
return 0, errOpNoSupport
|
||||
}
|
||||
|
||||
// SetHopLimit sets the hop limit field value for future outgoing
|
||||
// packets.
|
||||
func (c *genericOpt) SetHopLimit(hoplim int) error {
|
||||
// TODO(mikio): Implement this
|
||||
return errOpNoSupport
|
||||
}
|
||||
195
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/gentest.go
generated
vendored
195
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/gentest.go
generated
vendored
@@ -1,195 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build ignore
|
||||
|
||||
// This program generates internet protocol constants by reading IANA
|
||||
// protocol registries.
|
||||
//
|
||||
// Usage:
|
||||
// go run gentest.go > iana_test.go
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"go/format"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var registries = []struct {
|
||||
url string
|
||||
parse func(io.Writer, io.Reader) error
|
||||
}{
|
||||
{
|
||||
"http://www.iana.org/assignments/dscp-registry/dscp-registry.xml",
|
||||
parseDSCPRegistry,
|
||||
},
|
||||
{
|
||||
"http://www.iana.org/assignments/ipv4-tos-byte/ipv4-tos-byte.xml",
|
||||
parseTOSTCByte,
|
||||
},
|
||||
}
|
||||
|
||||
func main() {
|
||||
var bb bytes.Buffer
|
||||
fmt.Fprintf(&bb, "// go run gentest.go\n")
|
||||
fmt.Fprintf(&bb, "// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT\n\n")
|
||||
fmt.Fprintf(&bb, "package ipv6_test\n\n")
|
||||
for _, r := range registries {
|
||||
resp, err := http.Get(r.url)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
fmt.Fprintf(os.Stderr, "got HTTP status code %v for %v\n", resp.StatusCode, r.url)
|
||||
os.Exit(1)
|
||||
}
|
||||
if err := r.parse(&bb, resp.Body); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Fprintf(&bb, "\n")
|
||||
}
|
||||
b, err := format.Source(bb.Bytes())
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
os.Stdout.Write(b)
|
||||
}
|
||||
|
||||
func parseDSCPRegistry(w io.Writer, r io.Reader) error {
|
||||
dec := xml.NewDecoder(r)
|
||||
var dr dscpRegistry
|
||||
if err := dec.Decode(&dr); err != nil {
|
||||
return err
|
||||
}
|
||||
drs := dr.escape()
|
||||
fmt.Fprintf(w, "// %s, Updated: %s\n", dr.Title, dr.Updated)
|
||||
fmt.Fprintf(w, "const (\n")
|
||||
for _, dr := range drs {
|
||||
fmt.Fprintf(w, "DiffServ%s = %#x", dr.Name, dr.Value)
|
||||
fmt.Fprintf(w, "// %s\n", dr.OrigName)
|
||||
}
|
||||
fmt.Fprintf(w, ")\n")
|
||||
return nil
|
||||
}
|
||||
|
||||
type dscpRegistry struct {
|
||||
XMLName xml.Name `xml:"registry"`
|
||||
Title string `xml:"title"`
|
||||
Updated string `xml:"updated"`
|
||||
Note string `xml:"note"`
|
||||
RegTitle string `xml:"registry>title"`
|
||||
PoolRecords []struct {
|
||||
Name string `xml:"name"`
|
||||
Space string `xml:"space"`
|
||||
} `xml:"registry>record"`
|
||||
Records []struct {
|
||||
Name string `xml:"name"`
|
||||
Space string `xml:"space"`
|
||||
} `xml:"registry>registry>record"`
|
||||
}
|
||||
|
||||
type canonDSCPRecord struct {
|
||||
OrigName string
|
||||
Name string
|
||||
Value int
|
||||
}
|
||||
|
||||
func (drr *dscpRegistry) escape() []canonDSCPRecord {
|
||||
drs := make([]canonDSCPRecord, len(drr.Records))
|
||||
sr := strings.NewReplacer(
|
||||
"+", "",
|
||||
"-", "",
|
||||
"/", "",
|
||||
".", "",
|
||||
" ", "",
|
||||
)
|
||||
for i, dr := range drr.Records {
|
||||
s := strings.TrimSpace(dr.Name)
|
||||
drs[i].OrigName = s
|
||||
drs[i].Name = sr.Replace(s)
|
||||
n, err := strconv.ParseUint(dr.Space, 2, 8)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
drs[i].Value = int(n) << 2
|
||||
}
|
||||
return drs
|
||||
}
|
||||
|
||||
func parseTOSTCByte(w io.Writer, r io.Reader) error {
|
||||
dec := xml.NewDecoder(r)
|
||||
var ttb tosTCByte
|
||||
if err := dec.Decode(&ttb); err != nil {
|
||||
return err
|
||||
}
|
||||
trs := ttb.escape()
|
||||
fmt.Fprintf(w, "// %s, Updated: %s\n", ttb.Title, ttb.Updated)
|
||||
fmt.Fprintf(w, "const (\n")
|
||||
for _, tr := range trs {
|
||||
fmt.Fprintf(w, "%s = %#x", tr.Keyword, tr.Value)
|
||||
fmt.Fprintf(w, "// %s\n", tr.OrigKeyword)
|
||||
}
|
||||
fmt.Fprintf(w, ")\n")
|
||||
return nil
|
||||
}
|
||||
|
||||
type tosTCByte struct {
|
||||
XMLName xml.Name `xml:"registry"`
|
||||
Title string `xml:"title"`
|
||||
Updated string `xml:"updated"`
|
||||
Note string `xml:"note"`
|
||||
RegTitle string `xml:"registry>title"`
|
||||
Records []struct {
|
||||
Binary string `xml:"binary"`
|
||||
Keyword string `xml:"keyword"`
|
||||
} `xml:"registry>record"`
|
||||
}
|
||||
|
||||
type canonTOSTCByteRecord struct {
|
||||
OrigKeyword string
|
||||
Keyword string
|
||||
Value int
|
||||
}
|
||||
|
||||
func (ttb *tosTCByte) escape() []canonTOSTCByteRecord {
|
||||
trs := make([]canonTOSTCByteRecord, len(ttb.Records))
|
||||
sr := strings.NewReplacer(
|
||||
"Capable", "",
|
||||
"(", "",
|
||||
")", "",
|
||||
"+", "",
|
||||
"-", "",
|
||||
"/", "",
|
||||
".", "",
|
||||
" ", "",
|
||||
)
|
||||
for i, tr := range ttb.Records {
|
||||
s := strings.TrimSpace(tr.Keyword)
|
||||
trs[i].OrigKeyword = s
|
||||
ss := strings.Split(s, " ")
|
||||
if len(ss) > 1 {
|
||||
trs[i].Keyword = strings.Join(ss[1:], " ")
|
||||
} else {
|
||||
trs[i].Keyword = ss[0]
|
||||
}
|
||||
trs[i].Keyword = sr.Replace(trs[i].Keyword)
|
||||
n, err := strconv.ParseUint(tr.Binary, 2, 8)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
trs[i].Value = int(n)
|
||||
}
|
||||
return trs
|
||||
}
|
||||
33
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/helper.go
generated
vendored
33
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/helper.go
generated
vendored
@@ -1,33 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
)
|
||||
|
||||
var errOpNoSupport = errors.New("operation not supported")
|
||||
|
||||
func boolint(b bool) int {
|
||||
if b {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func netAddrToIP16(a net.Addr) net.IP {
|
||||
switch v := a.(type) {
|
||||
case *net.UDPAddr:
|
||||
if ip := v.IP.To16(); ip != nil && ip.To4() == nil {
|
||||
return ip
|
||||
}
|
||||
case *net.IPAddr:
|
||||
if ip := v.IP.To16(); ip != nil && ip.To4() == nil {
|
||||
return ip
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
22
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/helper_stub.go
generated
vendored
22
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/helper_stub.go
generated
vendored
@@ -1,22 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build dragonfly plan9 solaris
|
||||
|
||||
package ipv6
|
||||
|
||||
func (c *genericOpt) sysfd() (int, error) {
|
||||
// TODO(mikio): Implement this
|
||||
return 0, errOpNoSupport
|
||||
}
|
||||
|
||||
func (c *dgramOpt) sysfd() (int, error) {
|
||||
// TODO(mikio): Implement this
|
||||
return 0, errOpNoSupport
|
||||
}
|
||||
|
||||
func (c *payloadHandler) sysfd() (int, error) {
|
||||
// TODO(mikio): Implement this
|
||||
return 0, errOpNoSupport
|
||||
}
|
||||
46
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/helper_unix.go
generated
vendored
46
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/helper_unix.go
generated
vendored
@@ -1,46 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build darwin freebsd linux netbsd openbsd
|
||||
|
||||
package ipv6
|
||||
|
||||
import (
|
||||
"net"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
func (c *genericOpt) sysfd() (int, error) {
|
||||
switch p := c.Conn.(type) {
|
||||
case *net.TCPConn, *net.UDPConn, *net.IPConn:
|
||||
return sysfd(p)
|
||||
}
|
||||
return 0, errInvalidConnType
|
||||
}
|
||||
|
||||
func (c *dgramOpt) sysfd() (int, error) {
|
||||
switch p := c.PacketConn.(type) {
|
||||
case *net.UDPConn, *net.IPConn:
|
||||
return sysfd(p.(net.Conn))
|
||||
}
|
||||
return 0, errInvalidConnType
|
||||
}
|
||||
|
||||
func (c *payloadHandler) sysfd() (int, error) {
|
||||
return sysfd(c.PacketConn.(net.Conn))
|
||||
}
|
||||
|
||||
func sysfd(c net.Conn) (int, error) {
|
||||
cv := reflect.ValueOf(c)
|
||||
switch ce := cv.Elem(); ce.Kind() {
|
||||
case reflect.Struct:
|
||||
nfd := ce.FieldByName("conn").FieldByName("fd")
|
||||
switch fe := nfd.Elem(); fe.Kind() {
|
||||
case reflect.Struct:
|
||||
fd := fe.FieldByName("sysfd")
|
||||
return int(fd.Int()), nil
|
||||
}
|
||||
}
|
||||
return 0, errInvalidConnType
|
||||
}
|
||||
45
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/helper_windows.go
generated
vendored
45
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/helper_windows.go
generated
vendored
@@ -1,45 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6
|
||||
|
||||
import (
|
||||
"net"
|
||||
"reflect"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func (c *genericOpt) sysfd() (syscall.Handle, error) {
|
||||
switch p := c.Conn.(type) {
|
||||
case *net.TCPConn, *net.UDPConn, *net.IPConn:
|
||||
return sysfd(p)
|
||||
}
|
||||
return syscall.InvalidHandle, errInvalidConnType
|
||||
}
|
||||
|
||||
func (c *dgramOpt) sysfd() (syscall.Handle, error) {
|
||||
switch p := c.PacketConn.(type) {
|
||||
case *net.UDPConn, *net.IPConn:
|
||||
return sysfd(p.(net.Conn))
|
||||
}
|
||||
return syscall.InvalidHandle, errInvalidConnType
|
||||
}
|
||||
|
||||
func (c *payloadHandler) sysfd() (syscall.Handle, error) {
|
||||
return sysfd(c.PacketConn.(net.Conn))
|
||||
}
|
||||
|
||||
func sysfd(c net.Conn) (syscall.Handle, error) {
|
||||
cv := reflect.ValueOf(c)
|
||||
switch ce := cv.Elem(); ce.Kind() {
|
||||
case reflect.Struct:
|
||||
netfd := ce.FieldByName("conn").FieldByName("fd")
|
||||
switch fe := netfd.Elem(); fe.Kind() {
|
||||
case reflect.Struct:
|
||||
fd := fe.FieldByName("sysfd")
|
||||
return syscall.Handle(fd.Uint()), nil
|
||||
}
|
||||
}
|
||||
return syscall.InvalidHandle, errInvalidConnType
|
||||
}
|
||||
224
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/iana.go
generated
vendored
224
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/iana.go
generated
vendored
@@ -1,224 +0,0 @@
|
||||
// go run gen.go
|
||||
// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
||||
|
||||
package ipv6
|
||||
|
||||
// Internet Control Message Protocol version 6 (ICMPv6) Parameters, Updated: 2013-07-03
|
||||
const (
|
||||
ICMPTypeDestinationUnreachable ICMPType = 1 // Destination Unreachable
|
||||
ICMPTypePacketTooBig ICMPType = 2 // Packet Too Big
|
||||
ICMPTypeTimeExceeded ICMPType = 3 // Time Exceeded
|
||||
ICMPTypeParameterProblem ICMPType = 4 // Parameter Problem
|
||||
ICMPTypeEchoRequest ICMPType = 128 // Echo Request
|
||||
ICMPTypeEchoReply ICMPType = 129 // Echo Reply
|
||||
ICMPTypeMulticastListenerQuery ICMPType = 130 // Multicast Listener Query
|
||||
ICMPTypeMulticastListenerReport ICMPType = 131 // Multicast Listener Report
|
||||
ICMPTypeMulticastListenerDone ICMPType = 132 // Multicast Listener Done
|
||||
ICMPTypeRouterSolicitation ICMPType = 133 // Router Solicitation
|
||||
ICMPTypeRouterAdvertisement ICMPType = 134 // Router Advertisement
|
||||
ICMPTypeNeighborSolicitation ICMPType = 135 // Neighbor Solicitation
|
||||
ICMPTypeNeighborAdvertisement ICMPType = 136 // Neighbor Advertisement
|
||||
ICMPTypeRedirect ICMPType = 137 // Redirect Message
|
||||
ICMPTypeRouterRenumbering ICMPType = 138 // Router Renumbering
|
||||
ICMPTypeNodeInformationQuery ICMPType = 139 // ICMP Node Information Query
|
||||
ICMPTypeNodeInformationResponse ICMPType = 140 // ICMP Node Information Response
|
||||
ICMPTypeInverseNeighborDiscoverySolicitation ICMPType = 141 // Inverse Neighbor Discovery Solicitation Message
|
||||
ICMPTypeInverseNeighborDiscoveryAdvertisement ICMPType = 142 // Inverse Neighbor Discovery Advertisement Message
|
||||
ICMPTypeVersion2MulticastListenerReport ICMPType = 143 // Version 2 Multicast Listener Report
|
||||
ICMPTypeHomeAgentAddressDiscoveryRequest ICMPType = 144 // Home Agent Address Discovery Request Message
|
||||
ICMPTypeHomeAgentAddressDiscoveryReply ICMPType = 145 // Home Agent Address Discovery Reply Message
|
||||
ICMPTypeMobilePrefixSolicitation ICMPType = 146 // Mobile Prefix Solicitation
|
||||
ICMPTypeMobilePrefixAdvertisement ICMPType = 147 // Mobile Prefix Advertisement
|
||||
ICMPTypeCertificationPathSolicitation ICMPType = 148 // Certification Path Solicitation Message
|
||||
ICMPTypeCertificationPathAdvertisement ICMPType = 149 // Certification Path Advertisement Message
|
||||
ICMPTypeMulticastRouterAdvertisement ICMPType = 151 // Multicast Router Advertisement
|
||||
ICMPTypeMulticastRouterSolicitation ICMPType = 152 // Multicast Router Solicitation
|
||||
ICMPTypeMulticastRouterTermination ICMPType = 153 // Multicast Router Termination
|
||||
ICMPTypeFMIPv6 ICMPType = 154 // FMIPv6 Messages
|
||||
ICMPTypeRPLControl ICMPType = 155 // RPL Control Message
|
||||
ICMPTypeILNPv6LocatorUpdate ICMPType = 156 // ILNPv6 Locator Update Message
|
||||
ICMPTypeDuplicateAddressRequest ICMPType = 157 // Duplicate Address Request
|
||||
ICMPTypeDuplicateAddressConfirmation ICMPType = 158 // Duplicate Address Confirmation
|
||||
)
|
||||
|
||||
// Internet Control Message Protocol version 6 (ICMPv6) Parameters, Updated: 2013-07-03
|
||||
var icmpTypes = map[ICMPType]string{
|
||||
1: "destination unreachable",
|
||||
2: "packet too big",
|
||||
3: "time exceeded",
|
||||
4: "parameter problem",
|
||||
128: "echo request",
|
||||
129: "echo reply",
|
||||
130: "multicast listener query",
|
||||
131: "multicast listener report",
|
||||
132: "multicast listener done",
|
||||
133: "router solicitation",
|
||||
134: "router advertisement",
|
||||
135: "neighbor solicitation",
|
||||
136: "neighbor advertisement",
|
||||
137: "redirect message",
|
||||
138: "router renumbering",
|
||||
139: "icmp node information query",
|
||||
140: "icmp node information response",
|
||||
141: "inverse neighbor discovery solicitation message",
|
||||
142: "inverse neighbor discovery advertisement message",
|
||||
143: "version 2 multicast listener report",
|
||||
144: "home agent address discovery request message",
|
||||
145: "home agent address discovery reply message",
|
||||
146: "mobile prefix solicitation",
|
||||
147: "mobile prefix advertisement",
|
||||
148: "certification path solicitation message",
|
||||
149: "certification path advertisement message",
|
||||
151: "multicast router advertisement",
|
||||
152: "multicast router solicitation",
|
||||
153: "multicast router termination",
|
||||
154: "fmipv6 messages",
|
||||
155: "rpl control message",
|
||||
156: "ilnpv6 locator update message",
|
||||
157: "duplicate address request",
|
||||
158: "duplicate address confirmation",
|
||||
}
|
||||
|
||||
// Protocol Numbers, Updated: 2013-02-17
|
||||
const (
|
||||
ianaProtocolHOPOPT = 0 // IPv6 Hop-by-Hop Option
|
||||
ianaProtocolICMP = 1 // Internet Control Message
|
||||
ianaProtocolIGMP = 2 // Internet Group Management
|
||||
ianaProtocolGGP = 3 // Gateway-to-Gateway
|
||||
ianaProtocolIPv4 = 4 // IPv4 encapsulation
|
||||
ianaProtocolST = 5 // Stream
|
||||
ianaProtocolTCP = 6 // Transmission Control
|
||||
ianaProtocolCBT = 7 // CBT
|
||||
ianaProtocolEGP = 8 // Exterior Gateway Protocol
|
||||
ianaProtocolIGP = 9 // any private interior gateway (used by Cisco for their IGRP)
|
||||
ianaProtocolBBNRCCMON = 10 // BBN RCC Monitoring
|
||||
ianaProtocolNVPII = 11 // Network Voice Protocol
|
||||
ianaProtocolPUP = 12 // PUP
|
||||
ianaProtocolARGUS = 13 // ARGUS
|
||||
ianaProtocolEMCON = 14 // EMCON
|
||||
ianaProtocolXNET = 15 // Cross Net Debugger
|
||||
ianaProtocolCHAOS = 16 // Chaos
|
||||
ianaProtocolUDP = 17 // User Datagram
|
||||
ianaProtocolMUX = 18 // Multiplexing
|
||||
ianaProtocolDCNMEAS = 19 // DCN Measurement Subsystems
|
||||
ianaProtocolHMP = 20 // Host Monitoring
|
||||
ianaProtocolPRM = 21 // Packet Radio Measurement
|
||||
ianaProtocolXNSIDP = 22 // XEROX NS IDP
|
||||
ianaProtocolTRUNK1 = 23 // Trunk-1
|
||||
ianaProtocolTRUNK2 = 24 // Trunk-2
|
||||
ianaProtocolLEAF1 = 25 // Leaf-1
|
||||
ianaProtocolLEAF2 = 26 // Leaf-2
|
||||
ianaProtocolRDP = 27 // Reliable Data Protocol
|
||||
ianaProtocolIRTP = 28 // Internet Reliable Transaction
|
||||
ianaProtocolISOTP4 = 29 // ISO Transport Protocol Class 4
|
||||
ianaProtocolNETBLT = 30 // Bulk Data Transfer Protocol
|
||||
ianaProtocolMFENSP = 31 // MFE Network Services Protocol
|
||||
ianaProtocolMERITINP = 32 // MERIT Internodal Protocol
|
||||
ianaProtocolDCCP = 33 // Datagram Congestion Control Protocol
|
||||
ianaProtocol3PC = 34 // Third Party Connect Protocol
|
||||
ianaProtocolIDPR = 35 // Inter-Domain Policy Routing Protocol
|
||||
ianaProtocolXTP = 36 // XTP
|
||||
ianaProtocolDDP = 37 // Datagram Delivery Protocol
|
||||
ianaProtocolIDPRCMTP = 38 // IDPR Control Message Transport Proto
|
||||
ianaProtocolTPPP = 39 // TP++ Transport Protocol
|
||||
ianaProtocolIL = 40 // IL Transport Protocol
|
||||
ianaProtocolIPv6 = 41 // IPv6 encapsulation
|
||||
ianaProtocolSDRP = 42 // Source Demand Routing Protocol
|
||||
ianaProtocolIPv6Route = 43 // Routing Header for IPv6
|
||||
ianaProtocolIPv6Frag = 44 // Fragment Header for IPv6
|
||||
ianaProtocolIDRP = 45 // Inter-Domain Routing Protocol
|
||||
ianaProtocolRSVP = 46 // Reservation Protocol
|
||||
ianaProtocolGRE = 47 // Generic Routing Encapsulation
|
||||
ianaProtocolDSR = 48 // Dynamic Source Routing Protocol
|
||||
ianaProtocolBNA = 49 // BNA
|
||||
ianaProtocolESP = 50 // Encap Security Payload
|
||||
ianaProtocolAH = 51 // Authentication Header
|
||||
ianaProtocolINLSP = 52 // Integrated Net Layer Security TUBA
|
||||
ianaProtocolSWIPE = 53 // IP with Encryption
|
||||
ianaProtocolNARP = 54 // NBMA Address Resolution Protocol
|
||||
ianaProtocolMOBILE = 55 // IP Mobility
|
||||
ianaProtocolTLSP = 56 // Transport Layer Security Protocol using Kryptonet key management
|
||||
ianaProtocolSKIP = 57 // SKIP
|
||||
ianaProtocolIPv6ICMP = 58 // ICMP for IPv6
|
||||
ianaProtocolIPv6NoNxt = 59 // No Next Header for IPv6
|
||||
ianaProtocolIPv6Opts = 60 // Destination Options for IPv6
|
||||
ianaProtocolCFTP = 62 // CFTP
|
||||
ianaProtocolSATEXPAK = 64 // SATNET and Backroom EXPAK
|
||||
ianaProtocolKRYPTOLAN = 65 // Kryptolan
|
||||
ianaProtocolRVD = 66 // MIT Remote Virtual Disk Protocol
|
||||
ianaProtocolIPPC = 67 // Internet Pluribus Packet Core
|
||||
ianaProtocolSATMON = 69 // SATNET Monitoring
|
||||
ianaProtocolVISA = 70 // VISA Protocol
|
||||
ianaProtocolIPCV = 71 // Internet Packet Core Utility
|
||||
ianaProtocolCPNX = 72 // Computer Protocol Network Executive
|
||||
ianaProtocolCPHB = 73 // Computer Protocol Heart Beat
|
||||
ianaProtocolWSN = 74 // Wang Span Network
|
||||
ianaProtocolPVP = 75 // Packet Video Protocol
|
||||
ianaProtocolBRSATMON = 76 // Backroom SATNET Monitoring
|
||||
ianaProtocolSUNND = 77 // SUN ND PROTOCOL-Temporary
|
||||
ianaProtocolWBMON = 78 // WIDEBAND Monitoring
|
||||
ianaProtocolWBEXPAK = 79 // WIDEBAND EXPAK
|
||||
ianaProtocolISOIP = 80 // ISO Internet Protocol
|
||||
ianaProtocolVMTP = 81 // VMTP
|
||||
ianaProtocolSECUREVMTP = 82 // SECURE-VMTP
|
||||
ianaProtocolVINES = 83 // VINES
|
||||
ianaProtocolTTP = 84 // TTP
|
||||
ianaProtocolIPTM = 84 // Protocol Internet Protocol Traffic Manager
|
||||
ianaProtocolNSFNETIGP = 85 // NSFNET-IGP
|
||||
ianaProtocolDGP = 86 // Dissimilar Gateway Protocol
|
||||
ianaProtocolTCF = 87 // TCF
|
||||
ianaProtocolEIGRP = 88 // EIGRP
|
||||
ianaProtocolOSPFIGP = 89 // OSPFIGP
|
||||
ianaProtocolSpriteRPC = 90 // Sprite RPC Protocol
|
||||
ianaProtocolLARP = 91 // Locus Address Resolution Protocol
|
||||
ianaProtocolMTP = 92 // Multicast Transport Protocol
|
||||
ianaProtocolAX25 = 93 // AX.25 Frames
|
||||
ianaProtocolIPIP = 94 // IP-within-IP Encapsulation Protocol
|
||||
ianaProtocolMICP = 95 // Mobile Internetworking Control Pro.
|
||||
ianaProtocolSCCSP = 96 // Semaphore Communications Sec. Pro.
|
||||
ianaProtocolETHERIP = 97 // Ethernet-within-IP Encapsulation
|
||||
ianaProtocolENCAP = 98 // Encapsulation Header
|
||||
ianaProtocolGMTP = 100 // GMTP
|
||||
ianaProtocolIFMP = 101 // Ipsilon Flow Management Protocol
|
||||
ianaProtocolPNNI = 102 // PNNI over IP
|
||||
ianaProtocolPIM = 103 // Protocol Independent Multicast
|
||||
ianaProtocolARIS = 104 // ARIS
|
||||
ianaProtocolSCPS = 105 // SCPS
|
||||
ianaProtocolQNX = 106 // QNX
|
||||
ianaProtocolAN = 107 // Active Networks
|
||||
ianaProtocolIPComp = 108 // IP Payload Compression Protocol
|
||||
ianaProtocolSNP = 109 // Sitara Networks Protocol
|
||||
ianaProtocolCompaqPeer = 110 // Compaq Peer Protocol
|
||||
ianaProtocolIPXinIP = 111 // IPX in IP
|
||||
ianaProtocolVRRP = 112 // Virtual Router Redundancy Protocol
|
||||
ianaProtocolPGM = 113 // PGM Reliable Transport Protocol
|
||||
ianaProtocolL2TP = 115 // Layer Two Tunneling Protocol
|
||||
ianaProtocolDDX = 116 // D-II Data Exchange (DDX)
|
||||
ianaProtocolIATP = 117 // Interactive Agent Transfer Protocol
|
||||
ianaProtocolSTP = 118 // Schedule Transfer Protocol
|
||||
ianaProtocolSRP = 119 // SpectraLink Radio Protocol
|
||||
ianaProtocolUTI = 120 // UTI
|
||||
ianaProtocolSMP = 121 // Simple Message Protocol
|
||||
ianaProtocolSM = 122 // SM
|
||||
ianaProtocolPTP = 123 // Performance Transparency Protocol
|
||||
ianaProtocolISIS = 124 // ISIS over IPv4
|
||||
ianaProtocolFIRE = 125 // FIRE
|
||||
ianaProtocolCRTP = 126 // Combat Radio Transport Protocol
|
||||
ianaProtocolCRUDP = 127 // Combat Radio User Datagram
|
||||
ianaProtocolSSCOPMCE = 128 // SSCOPMCE
|
||||
ianaProtocolIPLT = 129 // IPLT
|
||||
ianaProtocolSPS = 130 // Secure Packet Shield
|
||||
ianaProtocolPIPE = 131 // Private IP Encapsulation within IP
|
||||
ianaProtocolSCTP = 132 // Stream Control Transmission Protocol
|
||||
ianaProtocolFC = 133 // Fibre Channel
|
||||
ianaProtocolRSVPE2EIGNORE = 134 // RSVP-E2E-IGNORE
|
||||
ianaProtocolMobilityHeader = 135 // Mobility Header
|
||||
ianaProtocolUDPLite = 136 // UDPLite
|
||||
ianaProtocolMPLSinIP = 137 // MPLS-in-IP
|
||||
ianaProtocolMANET = 138 // MANET Protocols
|
||||
ianaProtocolHIP = 139 // Host Identity Protocol
|
||||
ianaProtocolShim6 = 140 // Shim6 Protocol
|
||||
ianaProtocolWESP = 141 // Wrapped Encapsulating Security Payload
|
||||
ianaProtocolROHC = 142 // Robust Header Compression
|
||||
ianaProtocolReserved = 255 // Reserved
|
||||
)
|
||||
38
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/iana_test.go
generated
vendored
38
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/iana_test.go
generated
vendored
@@ -1,38 +0,0 @@
|
||||
// go run gentest.go
|
||||
// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
||||
|
||||
package ipv6_test
|
||||
|
||||
// Differentiated Services Field Codepoints (DSCP), Updated: 2013-06-25
|
||||
const (
|
||||
DiffServCS0 = 0x0 // CS0
|
||||
DiffServCS1 = 0x20 // CS1
|
||||
DiffServCS2 = 0x40 // CS2
|
||||
DiffServCS3 = 0x60 // CS3
|
||||
DiffServCS4 = 0x80 // CS4
|
||||
DiffServCS5 = 0xa0 // CS5
|
||||
DiffServCS6 = 0xc0 // CS6
|
||||
DiffServCS7 = 0xe0 // CS7
|
||||
DiffServAF11 = 0x28 // AF11
|
||||
DiffServAF12 = 0x30 // AF12
|
||||
DiffServAF13 = 0x38 // AF13
|
||||
DiffServAF21 = 0x48 // AF21
|
||||
DiffServAF22 = 0x50 // AF22
|
||||
DiffServAF23 = 0x58 // AF23
|
||||
DiffServAF31 = 0x68 // AF31
|
||||
DiffServAF32 = 0x70 // AF32
|
||||
DiffServAF33 = 0x78 // AF33
|
||||
DiffServAF41 = 0x88 // AF41
|
||||
DiffServAF42 = 0x90 // AF42
|
||||
DiffServAF43 = 0x98 // AF43
|
||||
DiffServEFPHB = 0xb8 // EF PHB
|
||||
DiffServVOICEADMIT = 0xb0 // VOICE-ADMIT
|
||||
)
|
||||
|
||||
// IPv4 TOS Byte and IPv6 Traffic Class Octet, Updated: 2001-09-06
|
||||
const (
|
||||
NotECNTransport = 0x0 // Not-ECT (Not ECN-Capable Transport)
|
||||
ECNTransport1 = 0x1 // ECT(1) (ECN-Capable Transport(1))
|
||||
ECNTransport0 = 0x2 // ECT(0) (ECN-Capable Transport(0))
|
||||
CongestionExperienced = 0x3 // CE (Congestion Experienced)
|
||||
)
|
||||
47
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/icmp.go
generated
vendored
47
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/icmp.go
generated
vendored
@@ -1,47 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6
|
||||
|
||||
import "sync"
|
||||
|
||||
// An ICMPType represents a type of ICMP message.
|
||||
type ICMPType int
|
||||
|
||||
func (typ ICMPType) String() string {
|
||||
s, ok := icmpTypes[typ]
|
||||
if !ok {
|
||||
return "<nil>"
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// An ICMPFilter represents an ICMP message filter for incoming
|
||||
// packets.
|
||||
type ICMPFilter struct {
|
||||
mu sync.RWMutex
|
||||
sysICMPFilter
|
||||
}
|
||||
|
||||
// Set sets the ICMP type and filter action to the filter.
|
||||
func (f *ICMPFilter) Set(typ ICMPType, block bool) {
|
||||
f.mu.Lock()
|
||||
f.set(typ, block)
|
||||
f.mu.Unlock()
|
||||
}
|
||||
|
||||
// SetAll sets the filter action to the filter.
|
||||
func (f *ICMPFilter) SetAll(block bool) {
|
||||
f.mu.Lock()
|
||||
f.setAll(block)
|
||||
f.mu.Unlock()
|
||||
}
|
||||
|
||||
// WillBlock reports whether the ICMP type will be blocked.
|
||||
func (f *ICMPFilter) WillBlock(typ ICMPType) bool {
|
||||
f.mu.RLock()
|
||||
ok := f.willBlock(typ)
|
||||
f.mu.RUnlock()
|
||||
return ok
|
||||
}
|
||||
33
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/icmp_bsd.go
generated
vendored
33
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/icmp_bsd.go
generated
vendored
@@ -1,33 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build darwin freebsd netbsd openbsd
|
||||
|
||||
package ipv6
|
||||
|
||||
type sysICMPFilter struct {
|
||||
Filt [8]uint32
|
||||
}
|
||||
|
||||
func (f *sysICMPFilter) set(typ ICMPType, block bool) {
|
||||
if block {
|
||||
f.Filt[typ>>5] &^= 1 << (uint32(typ) & 31)
|
||||
} else {
|
||||
f.Filt[typ>>5] |= 1 << (uint32(typ) & 31)
|
||||
}
|
||||
}
|
||||
|
||||
func (f *sysICMPFilter) setAll(block bool) {
|
||||
for i := range f.Filt {
|
||||
if block {
|
||||
f.Filt[i] = 0
|
||||
} else {
|
||||
f.Filt[i] = 1<<32 - 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (f *sysICMPFilter) willBlock(typ ICMPType) bool {
|
||||
return f.Filt[typ>>5]&(1<<(uint32(typ)&31)) == 0
|
||||
}
|
||||
31
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/icmp_linux.go
generated
vendored
31
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/icmp_linux.go
generated
vendored
@@ -1,31 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6
|
||||
|
||||
type sysICMPFilter struct {
|
||||
Data [8]uint32
|
||||
}
|
||||
|
||||
func (f *sysICMPFilter) set(typ ICMPType, block bool) {
|
||||
if block {
|
||||
f.Data[typ>>5] |= 1 << (uint32(typ) & 31)
|
||||
} else {
|
||||
f.Data[typ>>5] &^= 1 << (uint32(typ) & 31)
|
||||
}
|
||||
}
|
||||
|
||||
func (f *sysICMPFilter) setAll(block bool) {
|
||||
for i := range f.Data {
|
||||
if block {
|
||||
f.Data[i] = 1<<32 - 1
|
||||
} else {
|
||||
f.Data[i] = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (f *sysICMPFilter) willBlock(typ ICMPType) bool {
|
||||
return f.Data[typ>>5]&(1<<(uint32(typ)&31)) != 0
|
||||
}
|
||||
24
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/icmp_stub.go
generated
vendored
24
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/icmp_stub.go
generated
vendored
@@ -1,24 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build dragonfly plan9 solaris
|
||||
|
||||
package ipv6
|
||||
|
||||
type sysICMPFilter struct {
|
||||
// TODO(mikio): Implement this
|
||||
}
|
||||
|
||||
func (f *sysICMPFilter) set(typ ICMPType, block bool) {
|
||||
// TODO(mikio): Implement this
|
||||
}
|
||||
|
||||
func (f *sysICMPFilter) setAll(block bool) {
|
||||
// TODO(mikio): Implement this
|
||||
}
|
||||
|
||||
func (f *sysICMPFilter) willBlock(typ ICMPType) bool {
|
||||
// TODO(mikio): Implement this
|
||||
return false
|
||||
}
|
||||
102
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/icmp_test.go
generated
vendored
102
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/icmp_test.go
generated
vendored
@@ -1,102 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6_test
|
||||
|
||||
import (
|
||||
"code.google.com/p/go.net/ipv6"
|
||||
"net"
|
||||
"os"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"sync"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var icmpStringTests = []struct {
|
||||
in ipv6.ICMPType
|
||||
out string
|
||||
}{
|
||||
{ipv6.ICMPTypeDestinationUnreachable, "destination unreachable"},
|
||||
|
||||
{256, "<nil>"},
|
||||
}
|
||||
|
||||
func TestICMPString(t *testing.T) {
|
||||
for _, tt := range icmpStringTests {
|
||||
s := tt.in.String()
|
||||
if s != tt.out {
|
||||
t.Errorf("got %s; expected %s", s, tt.out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestICMPFilter(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "dragonfly", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %q", runtime.GOOS)
|
||||
}
|
||||
|
||||
var f ipv6.ICMPFilter
|
||||
for _, toggle := range []bool{false, true} {
|
||||
f.SetAll(toggle)
|
||||
var wg sync.WaitGroup
|
||||
for _, typ := range []ipv6.ICMPType{
|
||||
ipv6.ICMPTypeDestinationUnreachable,
|
||||
ipv6.ICMPTypeEchoReply,
|
||||
ipv6.ICMPTypeNeighborSolicitation,
|
||||
ipv6.ICMPTypeDuplicateAddressConfirmation,
|
||||
} {
|
||||
wg.Add(1)
|
||||
go func(typ ipv6.ICMPType) {
|
||||
defer wg.Done()
|
||||
f.Set(typ, false)
|
||||
if f.WillBlock(typ) {
|
||||
t.Errorf("ipv6.ICMPFilter.Set(%v, false) failed", typ)
|
||||
}
|
||||
f.Set(typ, true)
|
||||
if !f.WillBlock(typ) {
|
||||
t.Errorf("ipv6.ICMPFilter.Set(%v, true) failed", typ)
|
||||
}
|
||||
}(typ)
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetICMPFilter(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "dragonfly", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %q", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
t.Skip("ipv6 is not supported")
|
||||
}
|
||||
if os.Getuid() != 0 {
|
||||
t.Skip("must be root")
|
||||
}
|
||||
|
||||
c, err := net.ListenPacket("ip6:ipv6-icmp", "::1")
|
||||
if err != nil {
|
||||
t.Fatalf("net.ListenPacket failed: %v", err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
p := ipv6.NewPacketConn(c)
|
||||
|
||||
var f ipv6.ICMPFilter
|
||||
f.SetAll(true)
|
||||
f.Set(ipv6.ICMPTypeEchoRequest, false)
|
||||
f.Set(ipv6.ICMPTypeEchoReply, false)
|
||||
if err := p.SetICMPFilter(&f); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.SetICMPFilter failed: %v", err)
|
||||
}
|
||||
kf, err := p.ICMPFilter()
|
||||
if err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.ICMPFilter failed: %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(kf, &f) {
|
||||
t.Fatalf("got unexpected filter %#v; expected %#v", kf, f)
|
||||
}
|
||||
}
|
||||
22
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/icmp_windows.go
generated
vendored
22
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/icmp_windows.go
generated
vendored
@@ -1,22 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6
|
||||
|
||||
type sysICMPFilter struct {
|
||||
// TODO(mikio): Implement this
|
||||
}
|
||||
|
||||
func (f *sysICMPFilter) set(typ ICMPType, block bool) {
|
||||
// TODO(mikio): Implement this
|
||||
}
|
||||
|
||||
func (f *sysICMPFilter) setAll(block bool) {
|
||||
// TODO(mikio): Implement this
|
||||
}
|
||||
|
||||
func (f *sysICMPFilter) willBlock(typ ICMPType) bool {
|
||||
// TODO(mikio): Implement this
|
||||
return false
|
||||
}
|
||||
130
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/mockicmp_test.go
generated
vendored
130
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/mockicmp_test.go
generated
vendored
@@ -1,130 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6_test
|
||||
|
||||
import (
|
||||
"code.google.com/p/go.net/ipv6"
|
||||
"errors"
|
||||
"net"
|
||||
)
|
||||
|
||||
const (
|
||||
ipv6PseudoHeaderLen = 2*net.IPv6len + 8
|
||||
ianaProtocolIPv6ICMP = 58
|
||||
)
|
||||
|
||||
func ipv6PseudoHeader(src, dst net.IP, nextHeader int) []byte {
|
||||
b := make([]byte, ipv6PseudoHeaderLen)
|
||||
copy(b[:net.IPv6len], src)
|
||||
copy(b[net.IPv6len:], dst)
|
||||
b[len(b)-1] = byte(nextHeader)
|
||||
return b
|
||||
}
|
||||
|
||||
// icmpMessage represents an ICMP message.
|
||||
type icmpMessage struct {
|
||||
Type ipv6.ICMPType // type
|
||||
Code int // code
|
||||
Checksum int // checksum
|
||||
Body icmpMessageBody // body
|
||||
}
|
||||
|
||||
// icmpMessageBody represents an ICMP message body.
|
||||
type icmpMessageBody interface {
|
||||
Len() int
|
||||
Marshal() ([]byte, error)
|
||||
}
|
||||
|
||||
// Marshal returns the binary enconding of the ICMP echo request or
|
||||
// reply message m.
|
||||
func (m *icmpMessage) Marshal(psh []byte) ([]byte, error) {
|
||||
b := []byte{byte(m.Type), byte(m.Code), 0, 0}
|
||||
if psh != nil {
|
||||
b = append(psh, b...)
|
||||
}
|
||||
if m.Body != nil && m.Body.Len() != 0 {
|
||||
mb, err := m.Body.Marshal()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b = append(b, mb...)
|
||||
}
|
||||
if psh == nil {
|
||||
return b, nil
|
||||
}
|
||||
off, l := 2*net.IPv6len, len(b)-len(psh)
|
||||
b[off], b[off+1], b[off+2], b[off+3] = byte(l>>24), byte(l>>16), byte(l>>8), byte(l)
|
||||
csumcv := len(b) - 1 // checksum coverage
|
||||
s := uint32(0)
|
||||
for i := 0; i < csumcv; i += 2 {
|
||||
s += uint32(b[i+1])<<8 | uint32(b[i])
|
||||
}
|
||||
if csumcv&1 == 0 {
|
||||
s += uint32(b[csumcv])
|
||||
}
|
||||
s = s>>16 + s&0xffff
|
||||
s = s + s>>16
|
||||
// Place checksum back in header; using ^= avoids the
|
||||
// assumption the checksum bytes are zero.
|
||||
b[len(psh)+2] ^= byte(^s)
|
||||
b[len(psh)+3] ^= byte(^s >> 8)
|
||||
return b[len(psh):], nil
|
||||
}
|
||||
|
||||
// parseICMPMessage parses b as an ICMP message.
|
||||
func parseICMPMessage(b []byte) (*icmpMessage, error) {
|
||||
msglen := len(b)
|
||||
if msglen < 4 {
|
||||
return nil, errors.New("message too short")
|
||||
}
|
||||
m := &icmpMessage{Type: ipv6.ICMPType(b[0]), Code: int(b[1]), Checksum: int(b[2])<<8 | int(b[3])}
|
||||
if msglen > 4 {
|
||||
var err error
|
||||
switch m.Type {
|
||||
case ipv6.ICMPTypeEchoRequest, ipv6.ICMPTypeEchoReply:
|
||||
m.Body, err = parseICMPEcho(b[4:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// imcpEcho represenets an ICMP echo request or reply message body.
|
||||
type icmpEcho struct {
|
||||
ID int // identifier
|
||||
Seq int // sequence number
|
||||
Data []byte // data
|
||||
}
|
||||
|
||||
func (p *icmpEcho) Len() int {
|
||||
if p == nil {
|
||||
return 0
|
||||
}
|
||||
return 4 + len(p.Data)
|
||||
}
|
||||
|
||||
// Marshal returns the binary enconding of the ICMP echo request or
|
||||
// reply message body p.
|
||||
func (p *icmpEcho) Marshal() ([]byte, error) {
|
||||
b := make([]byte, 4+len(p.Data))
|
||||
b[0], b[1] = byte(p.ID>>8), byte(p.ID)
|
||||
b[2], b[3] = byte(p.Seq>>8), byte(p.Seq)
|
||||
copy(b[4:], p.Data)
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// parseICMPEcho parses b as an ICMP echo request or reply message
|
||||
// body.
|
||||
func parseICMPEcho(b []byte) (*icmpEcho, error) {
|
||||
bodylen := len(b)
|
||||
p := &icmpEcho{ID: int(b[0])<<8 | int(b[1]), Seq: int(b[2])<<8 | int(b[3])}
|
||||
if bodylen > 4 {
|
||||
p.Data = make([]byte, bodylen-4)
|
||||
copy(p.Data, b[4:])
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
88
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/mocktransponder_test.go
generated
vendored
88
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/mocktransponder_test.go
generated
vendored
@@ -1,88 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6_test
|
||||
|
||||
import (
|
||||
"net"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func isLinkLocalUnicast(ip net.IP) bool {
|
||||
return ip.To4() == nil && ip.To16() != nil && ip.IsLinkLocalUnicast()
|
||||
}
|
||||
|
||||
func loopbackInterface() *net.Interface {
|
||||
ift, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
for _, ifi := range ift {
|
||||
if ifi.Flags&net.FlagLoopback == 0 || ifi.Flags&net.FlagUp == 0 {
|
||||
continue
|
||||
}
|
||||
ifat, err := ifi.Addrs()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
for _, ifa := range ifat {
|
||||
switch ifa := ifa.(type) {
|
||||
case *net.IPAddr:
|
||||
if isLinkLocalUnicast(ifa.IP) {
|
||||
return &ifi
|
||||
}
|
||||
case *net.IPNet:
|
||||
if isLinkLocalUnicast(ifa.IP) {
|
||||
return &ifi
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func isMulticastAvailable(ifi *net.Interface) (net.IP, bool) {
|
||||
if ifi == nil || ifi.Flags&net.FlagUp == 0 || ifi.Flags&net.FlagMulticast == 0 {
|
||||
return nil, false
|
||||
}
|
||||
ifat, err := ifi.Addrs()
|
||||
if err != nil {
|
||||
return nil, false
|
||||
}
|
||||
for _, ifa := range ifat {
|
||||
switch ifa := ifa.(type) {
|
||||
case *net.IPAddr:
|
||||
if isLinkLocalUnicast(ifa.IP) {
|
||||
return ifa.IP, true
|
||||
}
|
||||
case *net.IPNet:
|
||||
if isLinkLocalUnicast(ifa.IP) {
|
||||
return ifa.IP, true
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func connector(t *testing.T, network, addr string, done chan<- bool) {
|
||||
defer func() { done <- true }()
|
||||
|
||||
c, err := net.Dial(network, addr)
|
||||
if err != nil {
|
||||
t.Errorf("net.Dial failed: %v", err)
|
||||
return
|
||||
}
|
||||
c.Close()
|
||||
}
|
||||
|
||||
func acceptor(t *testing.T, ln net.Listener, done chan<- bool) {
|
||||
defer func() { done <- true }()
|
||||
|
||||
c, err := ln.Accept()
|
||||
if err != nil {
|
||||
t.Errorf("net.Listener.Accept failed: %v", err)
|
||||
return
|
||||
}
|
||||
c.Close()
|
||||
}
|
||||
205
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/multicast_test.go
generated
vendored
205
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/multicast_test.go
generated
vendored
@@ -1,205 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"code.google.com/p/go.net/ipv6"
|
||||
"net"
|
||||
"os"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestPacketConnReadWriteMulticastUDP(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "freebsd": // due to a bug on loopback marking
|
||||
// See http://www.freebsd.org/cgi/query-pr.cgi?pr=180065.
|
||||
t.Skipf("not supported on %q", runtime.GOOS)
|
||||
case "dragonfly", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %q", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
t.Skip("ipv6 is not supported")
|
||||
}
|
||||
ifi := loopbackInterface()
|
||||
if ifi == nil {
|
||||
t.Skipf("not available on %q", runtime.GOOS)
|
||||
}
|
||||
|
||||
c, err := net.ListenPacket("udp6", "[ff02::114]:0") // see RFC 4727
|
||||
if err != nil {
|
||||
t.Fatalf("net.ListenPacket failed: %v", err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
_, port, err := net.SplitHostPort(c.LocalAddr().String())
|
||||
if err != nil {
|
||||
t.Fatalf("net.SplitHostPort failed: %v", err)
|
||||
}
|
||||
dst, err := net.ResolveUDPAddr("udp6", "[ff02::114]:"+port) // see RFC 4727
|
||||
if err != nil {
|
||||
t.Fatalf("net.ResolveUDPAddr failed: %v", err)
|
||||
}
|
||||
|
||||
p := ipv6.NewPacketConn(c)
|
||||
defer p.Close()
|
||||
if err := p.JoinGroup(ifi, dst); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.JoinGroup on %v failed: %v", ifi, err)
|
||||
}
|
||||
if err := p.SetMulticastInterface(ifi); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.SetMulticastInterface failed: %v", err)
|
||||
}
|
||||
if _, err := p.MulticastInterface(); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.MulticastInterface failed: %v", err)
|
||||
}
|
||||
if err := p.SetMulticastLoopback(true); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.SetMulticastLoopback failed: %v", err)
|
||||
}
|
||||
if _, err := p.MulticastLoopback(); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.MulticastLoopback failed: %v", err)
|
||||
}
|
||||
|
||||
cm := ipv6.ControlMessage{
|
||||
TrafficClass: DiffServAF11 | CongestionExperienced,
|
||||
Src: net.IPv6loopback,
|
||||
IfIndex: ifi.Index,
|
||||
}
|
||||
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
|
||||
wb := []byte("HELLO-R-U-THERE")
|
||||
|
||||
for i, toggle := range []bool{true, false, true} {
|
||||
if err := p.SetControlMessage(cf, toggle); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.SetControlMessage failed: %v", err)
|
||||
}
|
||||
if err := p.SetDeadline(time.Now().Add(200 * time.Millisecond)); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.SetDeadline failed: %v", err)
|
||||
}
|
||||
cm.HopLimit = i + 1
|
||||
if n, err := p.WriteTo(wb, &cm, dst); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.WriteTo failed: %v", err)
|
||||
} else if n != len(wb) {
|
||||
t.Fatalf("ipv6.PacketConn.WriteTo failed: short write: %v", n)
|
||||
}
|
||||
rb := make([]byte, 128)
|
||||
if n, cm, _, err := p.ReadFrom(rb); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.ReadFrom failed: %v", err)
|
||||
} else if !bytes.Equal(rb[:n], wb) {
|
||||
t.Fatalf("got %v; expected %v", rb[:n], wb)
|
||||
} else {
|
||||
t.Logf("rcvd cmsg: %v", cm)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPacketConnReadWriteMulticastICMP(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "dragonfly", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %q", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
t.Skip("ipv6 is not supported")
|
||||
}
|
||||
if os.Getuid() != 0 {
|
||||
t.Skip("must be root")
|
||||
}
|
||||
ifi := loopbackInterface()
|
||||
if ifi == nil {
|
||||
t.Skipf("not available on %q", runtime.GOOS)
|
||||
}
|
||||
|
||||
c, err := net.ListenPacket("ip6:ipv6-icmp", "::")
|
||||
if err != nil {
|
||||
t.Fatalf("net.ListenPacket failed: %v", err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
dst, err := net.ResolveIPAddr("ip6", "ff02::114") // see RFC 4727
|
||||
if err != nil {
|
||||
t.Fatalf("net.ResolveIPAddr failed: %v", err)
|
||||
}
|
||||
|
||||
pshicmp := ipv6PseudoHeader(c.LocalAddr().(*net.IPAddr).IP, dst.IP, ianaProtocolIPv6ICMP)
|
||||
p := ipv6.NewPacketConn(c)
|
||||
defer p.Close()
|
||||
if err := p.JoinGroup(ifi, dst); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.JoinGroup on %v failed: %v", ifi, err)
|
||||
}
|
||||
if err := p.SetMulticastInterface(ifi); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.SetMulticastInterface failed: %v", err)
|
||||
}
|
||||
if _, err := p.MulticastInterface(); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.MulticastInterface failed: %v", err)
|
||||
}
|
||||
if err := p.SetMulticastLoopback(true); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.SetMulticastLoopback failed: %v", err)
|
||||
}
|
||||
if _, err := p.MulticastLoopback(); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.MulticastLoopback failed: %v", err)
|
||||
}
|
||||
|
||||
cm := ipv6.ControlMessage{
|
||||
TrafficClass: DiffServAF11 | CongestionExperienced,
|
||||
Src: net.IPv6loopback,
|
||||
IfIndex: ifi.Index,
|
||||
}
|
||||
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
|
||||
|
||||
var f ipv6.ICMPFilter
|
||||
f.SetAll(true)
|
||||
f.Set(ipv6.ICMPTypeEchoReply, false)
|
||||
if err := p.SetICMPFilter(&f); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.SetICMPFilter failed: %v", err)
|
||||
}
|
||||
|
||||
var psh []byte
|
||||
for i, toggle := range []bool{true, false, true} {
|
||||
if toggle {
|
||||
psh = nil
|
||||
if err := p.SetChecksum(true, 2); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.SetChecksum failed: %v", err)
|
||||
}
|
||||
} else {
|
||||
psh = pshicmp
|
||||
// Some platforms never allow to disable the
|
||||
// kernel checksum processing.
|
||||
p.SetChecksum(false, -1)
|
||||
}
|
||||
wb, err := (&icmpMessage{
|
||||
Type: ipv6.ICMPTypeEchoRequest, Code: 0,
|
||||
Body: &icmpEcho{
|
||||
ID: os.Getpid() & 0xffff, Seq: i + 1,
|
||||
Data: []byte("HELLO-R-U-THERE"),
|
||||
},
|
||||
}).Marshal(psh)
|
||||
if err != nil {
|
||||
t.Fatalf("icmpMessage.Marshal failed: %v", err)
|
||||
}
|
||||
if err := p.SetControlMessage(cf, toggle); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.SetControlMessage failed: %v", err)
|
||||
}
|
||||
if err := p.SetDeadline(time.Now().Add(200 * time.Millisecond)); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.SetDeadline failed: %v", err)
|
||||
}
|
||||
cm.HopLimit = i + 1
|
||||
if n, err := p.WriteTo(wb, &cm, dst); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.WriteTo failed: %v", err)
|
||||
} else if n != len(wb) {
|
||||
t.Fatalf("ipv6.PacketConn.WriteTo failed: short write: %v", n)
|
||||
}
|
||||
rb := make([]byte, 128)
|
||||
if n, cm, _, err := p.ReadFrom(rb); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.ReadFrom failed: %v", err)
|
||||
} else {
|
||||
t.Logf("rcvd cmsg: %v", cm)
|
||||
if m, err := parseICMPMessage(rb[:n]); err != nil {
|
||||
t.Fatalf("parseICMPMessage failed: %v", err)
|
||||
} else if m.Type != ipv6.ICMPTypeEchoReply || m.Code != 0 {
|
||||
t.Fatalf("got type=%v, code=%v; expected type=%v, code=%v", m.Type, m.Code, ipv6.ICMPTypeEchoReply, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
243
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/multicastlistener_test.go
generated
vendored
243
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/multicastlistener_test.go
generated
vendored
@@ -1,243 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6_test
|
||||
|
||||
import (
|
||||
"code.google.com/p/go.net/ipv6"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"runtime"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var udpMultipleGroupListenerTests = []net.Addr{
|
||||
&net.UDPAddr{IP: net.ParseIP("ff02::114")}, // see RFC 4727
|
||||
&net.UDPAddr{IP: net.ParseIP("ff02::1:114")},
|
||||
&net.UDPAddr{IP: net.ParseIP("ff02::2:114")},
|
||||
}
|
||||
|
||||
func TestUDPSinglePacketConnWithMultipleGroupListeners(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "dragonfly", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %q", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
t.Skip("ipv6 is not supported")
|
||||
}
|
||||
|
||||
for _, gaddr := range udpMultipleGroupListenerTests {
|
||||
c, err := net.ListenPacket("udp6", "[::]:0") // wildcard address with non-reusable port
|
||||
if err != nil {
|
||||
t.Fatalf("net.ListenPacket failed: %v", err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
p := ipv6.NewPacketConn(c)
|
||||
var mift []*net.Interface
|
||||
|
||||
ift, err := net.Interfaces()
|
||||
if err != nil {
|
||||
t.Fatalf("net.Interfaces failed: %v", err)
|
||||
}
|
||||
for i, ifi := range ift {
|
||||
if _, ok := isMulticastAvailable(&ifi); !ok {
|
||||
continue
|
||||
}
|
||||
if err := p.JoinGroup(&ifi, gaddr); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.JoinGroup %v on %v failed: %v", gaddr, ifi, err)
|
||||
}
|
||||
mift = append(mift, &ift[i])
|
||||
}
|
||||
for _, ifi := range mift {
|
||||
if err := p.LeaveGroup(ifi, gaddr); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.LeaveGroup %v on %v failed: %v", gaddr, ifi, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestUDPMultiplePacketConnWithMultipleGroupListeners(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "dragonfly", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %q", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
t.Skip("ipv6 is not supported")
|
||||
}
|
||||
|
||||
for _, gaddr := range udpMultipleGroupListenerTests {
|
||||
c1, err := net.ListenPacket("udp6", "[ff02::]:1024") // wildcard address with reusable port
|
||||
if err != nil {
|
||||
t.Fatalf("net.ListenPacket failed: %v", err)
|
||||
}
|
||||
defer c1.Close()
|
||||
|
||||
c2, err := net.ListenPacket("udp6", "[ff02::]:1024") // wildcard address with reusable port
|
||||
if err != nil {
|
||||
t.Fatalf("net.ListenPacket failed: %v", err)
|
||||
}
|
||||
defer c2.Close()
|
||||
|
||||
var ps [2]*ipv6.PacketConn
|
||||
ps[0] = ipv6.NewPacketConn(c1)
|
||||
ps[1] = ipv6.NewPacketConn(c2)
|
||||
var mift []*net.Interface
|
||||
|
||||
ift, err := net.Interfaces()
|
||||
if err != nil {
|
||||
t.Fatalf("net.Interfaces failed: %v", err)
|
||||
}
|
||||
for i, ifi := range ift {
|
||||
if _, ok := isMulticastAvailable(&ifi); !ok {
|
||||
continue
|
||||
}
|
||||
for _, p := range ps {
|
||||
if err := p.JoinGroup(&ifi, gaddr); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.JoinGroup %v on %v failed: %v", gaddr, ifi, err)
|
||||
}
|
||||
}
|
||||
mift = append(mift, &ift[i])
|
||||
}
|
||||
for _, ifi := range mift {
|
||||
for _, p := range ps {
|
||||
if err := p.LeaveGroup(ifi, gaddr); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.LeaveGroup %v on %v failed: %v", gaddr, ifi, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestUDPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "dragonfly", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %q", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
t.Skip("ipv6 is not supported")
|
||||
}
|
||||
|
||||
gaddr := net.IPAddr{IP: net.ParseIP("ff02::114")} // see RFC 4727
|
||||
type ml struct {
|
||||
c *ipv6.PacketConn
|
||||
ifi *net.Interface
|
||||
}
|
||||
var mlt []*ml
|
||||
|
||||
ift, err := net.Interfaces()
|
||||
if err != nil {
|
||||
t.Fatalf("net.Interfaces failed: %v", err)
|
||||
}
|
||||
for i, ifi := range ift {
|
||||
ip, ok := isMulticastAvailable(&ifi)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
c, err := net.ListenPacket("udp6", fmt.Sprintf("[%s%%%s]:1024", ip.String(), ifi.Name)) // unicast address with non-reusable port
|
||||
if err != nil {
|
||||
t.Fatalf("net.ListenPacket with %v failed: %v", ip, err)
|
||||
}
|
||||
defer c.Close()
|
||||
p := ipv6.NewPacketConn(c)
|
||||
if err := p.JoinGroup(&ifi, &gaddr); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.JoinGroup on %v failed: %v", ifi, err)
|
||||
}
|
||||
mlt = append(mlt, &ml{p, &ift[i]})
|
||||
}
|
||||
for _, m := range mlt {
|
||||
if err := m.c.LeaveGroup(m.ifi, &gaddr); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.LeaveGroup on %v failed: %v", m.ifi, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIPSinglePacketConnWithSingleGroupListener(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "dragonfly", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %q", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
t.Skip("ipv6 is not supported")
|
||||
}
|
||||
if os.Getuid() != 0 {
|
||||
t.Skip("must be root")
|
||||
}
|
||||
|
||||
c, err := net.ListenPacket("ip6:ipv6-icmp", "::") // wildcard address
|
||||
if err != nil {
|
||||
t.Fatalf("net.ListenPacket failed: %v", err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
p := ipv6.NewPacketConn(c)
|
||||
gaddr := net.IPAddr{IP: net.ParseIP("ff02::114")} // see RFC 4727
|
||||
var mift []*net.Interface
|
||||
|
||||
ift, err := net.Interfaces()
|
||||
if err != nil {
|
||||
t.Fatalf("net.Interfaces failed: %v", err)
|
||||
}
|
||||
for i, ifi := range ift {
|
||||
if _, ok := isMulticastAvailable(&ifi); !ok {
|
||||
continue
|
||||
}
|
||||
if err := p.JoinGroup(&ifi, &gaddr); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.JoinGroup on %v failed: %v", ifi, err)
|
||||
}
|
||||
mift = append(mift, &ift[i])
|
||||
}
|
||||
for _, ifi := range mift {
|
||||
if err := p.LeaveGroup(ifi, &gaddr); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.LeaveGroup on %v failed: %v", ifi, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "darwin", "dragonfly", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %q", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
t.Skip("ipv6 is not supported")
|
||||
}
|
||||
if os.Getuid() != 0 {
|
||||
t.Skip("must be root")
|
||||
}
|
||||
|
||||
gaddr := net.IPAddr{IP: net.ParseIP("ff02::114")} // see RFC 4727
|
||||
type ml struct {
|
||||
c *ipv6.PacketConn
|
||||
ifi *net.Interface
|
||||
}
|
||||
var mlt []*ml
|
||||
|
||||
ift, err := net.Interfaces()
|
||||
if err != nil {
|
||||
t.Fatalf("net.Interfaces failed: %v", err)
|
||||
}
|
||||
for i, ifi := range ift {
|
||||
ip, ok := isMulticastAvailable(&ifi)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
c, err := net.ListenPacket("ip6:ipv6-icmp", fmt.Sprintf("%s%%%s", ip.String(), ifi.Name)) // unicast address
|
||||
if err != nil {
|
||||
t.Fatalf("net.ListenPacket failed: %v", err)
|
||||
}
|
||||
defer c.Close()
|
||||
p := ipv6.NewPacketConn(c)
|
||||
if err := p.JoinGroup(&ifi, &gaddr); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.JoinGroup on %v failed: %v", ifi, err)
|
||||
}
|
||||
mlt = append(mlt, &ml{p, &ift[i]})
|
||||
}
|
||||
for _, m := range mlt {
|
||||
if err := m.c.LeaveGroup(m.ifi, &gaddr); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.LeaveGroup on %v failed: %v", m.ifi, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
76
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/multicastsockopt_test.go
generated
vendored
76
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/multicastsockopt_test.go
generated
vendored
@@ -1,76 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6_test
|
||||
|
||||
import (
|
||||
"code.google.com/p/go.net/ipv6"
|
||||
"net"
|
||||
"os"
|
||||
"runtime"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var packetConnMulticastSocketOptionTests = []struct {
|
||||
net, proto, addr string
|
||||
gaddr net.Addr
|
||||
}{
|
||||
{"udp6", "", "[ff02::]:0", &net.UDPAddr{IP: net.ParseIP("ff02::114")}}, // see RFC 4727
|
||||
{"ip6", ":ipv6-icmp", "::", &net.IPAddr{IP: net.ParseIP("ff02::114")}}, // see RFC 4727
|
||||
}
|
||||
|
||||
func TestPacketConnMulticastSocketOptions(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "dragonfly", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %q", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
t.Skip("ipv6 is not supported")
|
||||
}
|
||||
ifi := loopbackInterface()
|
||||
if ifi == nil {
|
||||
t.Skipf("not available on %q", runtime.GOOS)
|
||||
}
|
||||
|
||||
for _, tt := range packetConnMulticastSocketOptionTests {
|
||||
if tt.net == "ip6" && os.Getuid() != 0 {
|
||||
t.Skip("must be root")
|
||||
}
|
||||
c, err := net.ListenPacket(tt.net+tt.proto, tt.addr)
|
||||
if err != nil {
|
||||
t.Fatalf("net.ListenPacket failed: %v", err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
p := ipv6.NewPacketConn(c)
|
||||
|
||||
hoplim := 255
|
||||
if err := p.SetMulticastHopLimit(hoplim); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.SetMulticastHopLimit failed: %v", err)
|
||||
}
|
||||
if v, err := p.MulticastHopLimit(); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.MulticastHopLimit failed: %v", err)
|
||||
} else if v != hoplim {
|
||||
t.Fatalf("got unexpected multicast hop limit %v; expected %v", v, hoplim)
|
||||
}
|
||||
|
||||
for _, toggle := range []bool{true, false} {
|
||||
if err := p.SetMulticastLoopback(toggle); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.SetMulticastLoopback failed: %v", err)
|
||||
}
|
||||
if v, err := p.MulticastLoopback(); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.MulticastLoopback failed: %v", err)
|
||||
} else if v != toggle {
|
||||
t.Fatalf("got unexpected multicast loopback %v; expected %v", v, toggle)
|
||||
}
|
||||
}
|
||||
|
||||
if err := p.JoinGroup(ifi, tt.gaddr); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.JoinGroup(%v, %v) failed: %v", ifi, tt.gaddr, err)
|
||||
}
|
||||
if err := p.LeaveGroup(ifi, tt.gaddr); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.LeaveGroup(%v, %v) failed: %v", ifi, tt.gaddr, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
15
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/payload.go
generated
vendored
15
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/payload.go
generated
vendored
@@ -1,15 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6
|
||||
|
||||
import "net"
|
||||
|
||||
// A payloadHandler represents the IPv6 datagram payload handler.
|
||||
type payloadHandler struct {
|
||||
net.PacketConn
|
||||
rawOpt
|
||||
}
|
||||
|
||||
func (c *payloadHandler) ok() bool { return c != nil && c.PacketConn != nil }
|
||||
70
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/payload_cmsg.go
generated
vendored
70
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/payload_cmsg.go
generated
vendored
@@ -1,70 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !plan9,!windows
|
||||
|
||||
package ipv6
|
||||
|
||||
import (
|
||||
"net"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// ReadFrom reads a payload of the received IPv6 datagram, from the
|
||||
// endpoint c, copying the payload into b. It returns the number of
|
||||
// bytes copied into b, the control message cm and the source address
|
||||
// src of the received datagram.
|
||||
func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) {
|
||||
if !c.ok() {
|
||||
return 0, nil, nil, syscall.EINVAL
|
||||
}
|
||||
oob := newControlMessage(&c.rawOpt)
|
||||
var oobn int
|
||||
switch c := c.PacketConn.(type) {
|
||||
case *net.UDPConn:
|
||||
if n, oobn, _, src, err = c.ReadMsgUDP(b, oob); err != nil {
|
||||
return 0, nil, nil, err
|
||||
}
|
||||
case *net.IPConn:
|
||||
if n, oobn, _, src, err = c.ReadMsgIP(b, oob); err != nil {
|
||||
return 0, nil, nil, err
|
||||
}
|
||||
default:
|
||||
return 0, nil, nil, errInvalidConnType
|
||||
}
|
||||
if cm, err = parseControlMessage(oob[:oobn]); err != nil {
|
||||
return 0, nil, nil, err
|
||||
}
|
||||
if cm != nil {
|
||||
cm.Src = netAddrToIP16(src)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// WriteTo writes a payload of the IPv6 datagram, to the destination
|
||||
// address dst through the endpoint c, copying the payload from b. It
|
||||
// returns the number of bytes written. The control message cm allows
|
||||
// the IPv6 header fields and the datagram path to be specified. The
|
||||
// cm may be nil if control of the outgoing datagram is not required.
|
||||
func (c *payloadHandler) WriteTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) {
|
||||
if !c.ok() {
|
||||
return 0, syscall.EINVAL
|
||||
}
|
||||
oob := marshalControlMessage(cm)
|
||||
if dst == nil {
|
||||
return 0, errMissingAddress
|
||||
}
|
||||
switch c := c.PacketConn.(type) {
|
||||
case *net.UDPConn:
|
||||
n, _, err = c.WriteMsgUDP(b, oob, dst.(*net.UDPAddr))
|
||||
case *net.IPConn:
|
||||
n, _, err = c.WriteMsgIP(b, oob, dst.(*net.IPAddr))
|
||||
default:
|
||||
return 0, errInvalidConnType
|
||||
}
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return
|
||||
}
|
||||
41
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/payload_noncmsg.go
generated
vendored
41
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/payload_noncmsg.go
generated
vendored
@@ -1,41 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build plan9 windows
|
||||
|
||||
package ipv6
|
||||
|
||||
import (
|
||||
"net"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// ReadFrom reads a payload of the received IPv6 datagram, from the
|
||||
// endpoint c, copying the payload into b. It returns the number of
|
||||
// bytes copied into b, the control message cm and the source address
|
||||
// src of the received datagram.
|
||||
func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) {
|
||||
if !c.ok() {
|
||||
return 0, nil, nil, syscall.EINVAL
|
||||
}
|
||||
if n, src, err = c.PacketConn.ReadFrom(b); err != nil {
|
||||
return 0, nil, nil, err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// WriteTo writes a payload of the IPv6 datagram, to the destination
|
||||
// address dst through the endpoint c, copying the payload from b. It
|
||||
// returns the number of bytes written. The control message cm allows
|
||||
// the IPv6 header fields and the datagram path to be specified. The
|
||||
// cm may be nil if control of the outgoing datagram is not required.
|
||||
func (c *payloadHandler) WriteTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) {
|
||||
if !c.ok() {
|
||||
return 0, syscall.EINVAL
|
||||
}
|
||||
if dst == nil {
|
||||
return 0, errMissingAddress
|
||||
}
|
||||
return c.PacketConn.WriteTo(b, dst)
|
||||
}
|
||||
168
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/readwrite_test.go
generated
vendored
168
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/readwrite_test.go
generated
vendored
@@ -1,168 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"code.google.com/p/go.net/ipv6"
|
||||
"net"
|
||||
"runtime"
|
||||
"sync"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func benchmarkUDPListener() (net.PacketConn, net.Addr, error) {
|
||||
c, err := net.ListenPacket("udp6", "[::1]:0")
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
dst, err := net.ResolveUDPAddr("udp6", c.LocalAddr().String())
|
||||
if err != nil {
|
||||
c.Close()
|
||||
return nil, nil, err
|
||||
}
|
||||
return c, dst, nil
|
||||
}
|
||||
|
||||
func BenchmarkReadWriteNetUDP(b *testing.B) {
|
||||
c, dst, err := benchmarkUDPListener()
|
||||
if err != nil {
|
||||
b.Fatalf("benchmarkUDPListener failed: %v", err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
wb, rb := []byte("HELLO-R-U-THERE"), make([]byte, 128)
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
benchmarkReadWriteNetUDP(b, c, wb, rb, dst)
|
||||
}
|
||||
}
|
||||
|
||||
func benchmarkReadWriteNetUDP(b *testing.B, c net.PacketConn, wb, rb []byte, dst net.Addr) {
|
||||
if _, err := c.WriteTo(wb, dst); err != nil {
|
||||
b.Fatalf("net.PacketConn.WriteTo failed: %v", err)
|
||||
}
|
||||
if _, _, err := c.ReadFrom(rb); err != nil {
|
||||
b.Fatalf("net.PacketConn.ReadFrom failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkReadWriteIPv6UDP(b *testing.B) {
|
||||
c, dst, err := benchmarkUDPListener()
|
||||
if err != nil {
|
||||
b.Fatalf("benchmarkUDPListener failed: %v", err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
p := ipv6.NewPacketConn(c)
|
||||
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagInterface | ipv6.FlagPathMTU
|
||||
if err := p.SetControlMessage(cf, true); err != nil {
|
||||
b.Fatalf("ipv6.PacketConn.SetControlMessage failed: %v", err)
|
||||
}
|
||||
ifi := loopbackInterface()
|
||||
|
||||
wb, rb := []byte("HELLO-R-U-THERE"), make([]byte, 128)
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
benchmarkReadWriteIPv6UDP(b, p, wb, rb, dst, ifi)
|
||||
}
|
||||
}
|
||||
|
||||
func benchmarkReadWriteIPv6UDP(b *testing.B, p *ipv6.PacketConn, wb, rb []byte, dst net.Addr, ifi *net.Interface) {
|
||||
cm := ipv6.ControlMessage{
|
||||
TrafficClass: DiffServAF11 | CongestionExperienced,
|
||||
HopLimit: 1,
|
||||
}
|
||||
if ifi != nil {
|
||||
cm.IfIndex = ifi.Index
|
||||
}
|
||||
if n, err := p.WriteTo(wb, &cm, dst); err != nil {
|
||||
b.Fatalf("ipv6.PacketConn.WriteTo failed: %v", err)
|
||||
} else if n != len(wb) {
|
||||
b.Fatalf("ipv6.PacketConn.WriteTo failed: short write: %v", n)
|
||||
}
|
||||
if _, _, _, err := p.ReadFrom(rb); err != nil {
|
||||
b.Fatalf("ipv6.PacketConn.ReadFrom failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPacketConnConcurrentReadWriteUnicastUDP(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "dragonfly", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %q", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
t.Skip("ipv6 is not supported")
|
||||
}
|
||||
|
||||
c, err := net.ListenPacket("udp6", "[::1]:0")
|
||||
if err != nil {
|
||||
t.Fatalf("net.ListenPacket failed: %v", err)
|
||||
}
|
||||
defer c.Close()
|
||||
p := ipv6.NewPacketConn(c)
|
||||
defer p.Close()
|
||||
|
||||
dst, err := net.ResolveUDPAddr("udp6", c.LocalAddr().String())
|
||||
if err != nil {
|
||||
t.Fatalf("net.ResolveUDPAddr failed: %v", err)
|
||||
}
|
||||
|
||||
ifi := loopbackInterface()
|
||||
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
|
||||
wb := []byte("HELLO-R-U-THERE")
|
||||
|
||||
var wg sync.WaitGroup
|
||||
reader := func() {
|
||||
defer wg.Done()
|
||||
rb := make([]byte, 128)
|
||||
if n, cm, _, err := p.ReadFrom(rb); err != nil {
|
||||
t.Errorf("ipv6.PacketConn.ReadFrom failed: %v", err)
|
||||
return
|
||||
} else if !bytes.Equal(rb[:n], wb) {
|
||||
t.Errorf("got %v; expected %v", rb[:n], wb)
|
||||
return
|
||||
} else {
|
||||
t.Logf("rcvd cmsg: %v", cm)
|
||||
}
|
||||
}
|
||||
writer := func(toggle bool) {
|
||||
defer wg.Done()
|
||||
cm := ipv6.ControlMessage{
|
||||
TrafficClass: DiffServAF11 | CongestionExperienced,
|
||||
Src: net.IPv6loopback,
|
||||
Dst: net.IPv6loopback,
|
||||
}
|
||||
if ifi != nil {
|
||||
cm.IfIndex = ifi.Index
|
||||
}
|
||||
if err := p.SetControlMessage(cf, toggle); err != nil {
|
||||
t.Errorf("ipv6.PacketConn.SetControlMessage failed: %v", err)
|
||||
return
|
||||
}
|
||||
if n, err := p.WriteTo(wb, &cm, dst); err != nil {
|
||||
t.Errorf("ipv6.PacketConn.WriteTo failed: %v", err)
|
||||
return
|
||||
} else if n != len(wb) {
|
||||
t.Errorf("ipv6.PacketConn.WriteTo failed: short write: %v", n)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
const N = 10
|
||||
wg.Add(N)
|
||||
for i := 0; i < N; i++ {
|
||||
go reader()
|
||||
}
|
||||
wg.Add(2 * N)
|
||||
for i := 0; i < 2*N; i++ {
|
||||
go writer(i%2 != 0)
|
||||
}
|
||||
wg.Add(N)
|
||||
for i := 0; i < N; i++ {
|
||||
go reader()
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
73
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc2292_unix.go
generated
vendored
73
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc2292_unix.go
generated
vendored
@@ -1,73 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build darwin
|
||||
|
||||
package ipv6
|
||||
|
||||
import (
|
||||
"os"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func ipv6ReceiveTrafficClass(fd int) (bool, error) {
|
||||
return false, errOpNoSupport
|
||||
}
|
||||
|
||||
func setIPv6ReceiveTrafficClass(fd int, v bool) error {
|
||||
return errOpNoSupport
|
||||
}
|
||||
|
||||
func ipv6ReceiveHopLimit(fd int) (bool, error) {
|
||||
var v int32
|
||||
l := sysSockoptLen(4)
|
||||
if err := getsockopt(fd, ianaProtocolIPv6, sysSockopt2292HopLimit, uintptr(unsafe.Pointer(&v)), &l); err != nil {
|
||||
return false, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return v == 1, nil
|
||||
}
|
||||
|
||||
func setIPv6ReceiveHopLimit(fd int, v bool) error {
|
||||
vv := int32(boolint(v))
|
||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockopt2292HopLimit, uintptr(unsafe.Pointer(&vv)), 4))
|
||||
}
|
||||
|
||||
func ipv6ReceivePacketInfo(fd int) (bool, error) {
|
||||
var v int32
|
||||
l := sysSockoptLen(4)
|
||||
if err := getsockopt(fd, ianaProtocolIPv6, sysSockopt2292PacketInfo, uintptr(unsafe.Pointer(&v)), &l); err != nil {
|
||||
return false, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return v == 1, nil
|
||||
}
|
||||
|
||||
func setIPv6ReceivePacketInfo(fd int, v bool) error {
|
||||
vv := int32(boolint(v))
|
||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockopt2292PacketInfo, uintptr(unsafe.Pointer(&vv)), 4))
|
||||
}
|
||||
|
||||
func ipv6PathMTU(fd int) (int, error) {
|
||||
return 0, errOpNoSupport
|
||||
}
|
||||
|
||||
func ipv6ReceivePathMTU(fd int) (bool, error) {
|
||||
return false, errOpNoSupport
|
||||
}
|
||||
|
||||
func setIPv6ReceivePathMTU(fd int, v bool) error {
|
||||
return errOpNoSupport
|
||||
}
|
||||
|
||||
func ipv6ICMPFilter(fd int) (*ICMPFilter, error) {
|
||||
var v ICMPFilter
|
||||
l := sysSockoptLen(sysSizeofICMPFilter)
|
||||
if err := getsockopt(fd, ianaProtocolIPv6ICMP, sysSockoptICMPFilter, uintptr(unsafe.Pointer(&v.sysICMPFilter)), &l); err != nil {
|
||||
return nil, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return &v, nil
|
||||
}
|
||||
|
||||
func setIPv6ICMPFilter(fd int, f *ICMPFilter) error {
|
||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6ICMP, sysSockoptICMPFilter, uintptr(unsafe.Pointer(&f.sysICMPFilter)), sysSizeofICMPFilter))
|
||||
}
|
||||
20
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3493_bsd.go
generated
vendored
20
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3493_bsd.go
generated
vendored
@@ -1,20 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build darwin freebsd netbsd openbsd
|
||||
|
||||
package ipv6
|
||||
|
||||
import (
|
||||
"os"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func setIPv6Checksum(fd int, on bool, offset int) error {
|
||||
if !on {
|
||||
offset = -1
|
||||
}
|
||||
v := int32(offset)
|
||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptChecksum, uintptr(unsafe.Pointer(&v)), 4))
|
||||
}
|
||||
18
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3493_linux.go
generated
vendored
18
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3493_linux.go
generated
vendored
@@ -1,18 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6
|
||||
|
||||
import (
|
||||
"os"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func setIPv6Checksum(fd int, on bool, offset int) error {
|
||||
if !on {
|
||||
offset = -1
|
||||
}
|
||||
v := int32(offset)
|
||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolReserved, sysSockoptChecksum, uintptr(unsafe.Pointer(&v)), 4))
|
||||
}
|
||||
124
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3493_unix.go
generated
vendored
124
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3493_unix.go
generated
vendored
@@ -1,124 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build darwin freebsd linux netbsd openbsd
|
||||
|
||||
package ipv6
|
||||
|
||||
import (
|
||||
"net"
|
||||
"os"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func ipv6TrafficClass(fd int) (int, error) {
|
||||
var v int32
|
||||
l := sysSockoptLen(4)
|
||||
if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptTrafficClass, uintptr(unsafe.Pointer(&v)), &l); err != nil {
|
||||
return 0, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return int(v), nil
|
||||
}
|
||||
|
||||
func setIPv6TrafficClass(fd, v int) error {
|
||||
vv := int32(v)
|
||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptTrafficClass, uintptr(unsafe.Pointer(&vv)), 4))
|
||||
}
|
||||
|
||||
func ipv6HopLimit(fd int) (int, error) {
|
||||
var v int32
|
||||
l := sysSockoptLen(4)
|
||||
if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptUnicastHopLimit, uintptr(unsafe.Pointer(&v)), &l); err != nil {
|
||||
return 0, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return int(v), nil
|
||||
}
|
||||
|
||||
func setIPv6HopLimit(fd, v int) error {
|
||||
vv := int32(v)
|
||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptUnicastHopLimit, uintptr(unsafe.Pointer(&vv)), 4))
|
||||
}
|
||||
|
||||
func ipv6Checksum(fd int) (bool, int, error) {
|
||||
var v int32
|
||||
l := sysSockoptLen(4)
|
||||
if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptChecksum, uintptr(unsafe.Pointer(&v)), &l); err != nil {
|
||||
return false, 0, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
on := true
|
||||
if v == -1 {
|
||||
on = false
|
||||
}
|
||||
return on, int(v), nil
|
||||
}
|
||||
|
||||
func ipv6MulticastHopLimit(fd int) (int, error) {
|
||||
var v int32
|
||||
l := sysSockoptLen(4)
|
||||
if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastHopLimit, uintptr(unsafe.Pointer(&v)), &l); err != nil {
|
||||
return 0, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return int(v), nil
|
||||
}
|
||||
|
||||
func setIPv6MulticastHopLimit(fd, v int) error {
|
||||
vv := int32(v)
|
||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastHopLimit, uintptr(unsafe.Pointer(&vv)), 4))
|
||||
}
|
||||
|
||||
func ipv6MulticastInterface(fd int) (*net.Interface, error) {
|
||||
var v int32
|
||||
l := sysSockoptLen(4)
|
||||
if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastInterface, uintptr(unsafe.Pointer(&v)), &l); err != nil {
|
||||
return nil, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
if v == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
ifi, err := net.InterfaceByIndex(int(v))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ifi, nil
|
||||
}
|
||||
|
||||
func setIPv6MulticastInterface(fd int, ifi *net.Interface) error {
|
||||
var v int32
|
||||
if ifi != nil {
|
||||
v = int32(ifi.Index)
|
||||
}
|
||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastInterface, uintptr(unsafe.Pointer(&v)), 4))
|
||||
}
|
||||
|
||||
func ipv6MulticastLoopback(fd int) (bool, error) {
|
||||
var v int32
|
||||
l := sysSockoptLen(4)
|
||||
if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastLoopback, uintptr(unsafe.Pointer(&v)), &l); err != nil {
|
||||
return false, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return v == 1, nil
|
||||
}
|
||||
|
||||
func setIPv6MulticastLoopback(fd int, v bool) error {
|
||||
vv := int32(boolint(v))
|
||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastLoopback, uintptr(unsafe.Pointer(&vv)), 4))
|
||||
}
|
||||
|
||||
func joinIPv6Group(fd int, ifi *net.Interface, grp net.IP) error {
|
||||
mreq := sysMulticastReq{}
|
||||
copy(mreq.IP[:], grp)
|
||||
if ifi != nil {
|
||||
mreq.IfIndex = uint32(ifi.Index)
|
||||
}
|
||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptJoinGroup, uintptr(unsafe.Pointer(&mreq)), sysSizeofMulticastReq))
|
||||
}
|
||||
|
||||
func leaveIPv6Group(fd int, ifi *net.Interface, grp net.IP) error {
|
||||
mreq := sysMulticastReq{}
|
||||
copy(mreq.IP[:], grp)
|
||||
if ifi != nil {
|
||||
mreq.IfIndex = uint32(ifi.Index)
|
||||
}
|
||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptLeaveGroup, uintptr(unsafe.Pointer(&mreq)), sysSizeofMulticastReq))
|
||||
}
|
||||
116
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3493_windows.go
generated
vendored
116
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3493_windows.go
generated
vendored
@@ -1,116 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6
|
||||
|
||||
import (
|
||||
"net"
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func ipv6TrafficClass(fd syscall.Handle) (int, error) {
|
||||
// TODO(mikio): Implement this
|
||||
return 0, syscall.EWINDOWS
|
||||
}
|
||||
|
||||
func setIPv6TrafficClass(fd syscall.Handle, v int) error {
|
||||
// TODO(mikio): Implement this
|
||||
return syscall.EWINDOWS
|
||||
}
|
||||
|
||||
func ipv6HopLimit(fd syscall.Handle) (int, error) {
|
||||
var v int32
|
||||
l := int32(4)
|
||||
if err := syscall.Getsockopt(fd, ianaProtocolIPv6, sysSockoptUnicastHopLimit, (*byte)(unsafe.Pointer(&v)), &l); err != nil {
|
||||
return 0, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return int(v), nil
|
||||
}
|
||||
|
||||
func setIPv6HopLimit(fd syscall.Handle, v int) error {
|
||||
vv := int32(v)
|
||||
return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIPv6, sysSockoptUnicastHopLimit, (*byte)(unsafe.Pointer(&vv)), 4))
|
||||
}
|
||||
|
||||
func ipv6Checksum(fd syscall.Handle) (bool, int, error) {
|
||||
// TODO(mikio): Implement this
|
||||
return false, 0, syscall.EWINDOWS
|
||||
}
|
||||
|
||||
func ipv6MulticastHopLimit(fd syscall.Handle) (int, error) {
|
||||
var v int32
|
||||
l := int32(4)
|
||||
if err := syscall.Getsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastHopLimit, (*byte)(unsafe.Pointer(&v)), &l); err != nil {
|
||||
return 0, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return int(v), nil
|
||||
}
|
||||
|
||||
func setIPv6MulticastHopLimit(fd syscall.Handle, v int) error {
|
||||
vv := int32(v)
|
||||
return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastHopLimit, (*byte)(unsafe.Pointer(&vv)), 4))
|
||||
}
|
||||
|
||||
func ipv6MulticastInterface(fd syscall.Handle) (*net.Interface, error) {
|
||||
var v int32
|
||||
l := int32(4)
|
||||
if err := syscall.Getsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastInterface, (*byte)(unsafe.Pointer(&v)), &l); err != nil {
|
||||
return nil, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
if v == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
ifi, err := net.InterfaceByIndex(int(v))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ifi, nil
|
||||
}
|
||||
|
||||
func setIPv6MulticastInterface(fd syscall.Handle, ifi *net.Interface) error {
|
||||
var v int32
|
||||
if ifi != nil {
|
||||
v = int32(ifi.Index)
|
||||
}
|
||||
return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastInterface, (*byte)(unsafe.Pointer(&v)), 4))
|
||||
}
|
||||
|
||||
func ipv6MulticastLoopback(fd syscall.Handle) (bool, error) {
|
||||
var v int32
|
||||
l := int32(4)
|
||||
if err := syscall.Getsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastLoopback, (*byte)(unsafe.Pointer(&v)), &l); err != nil {
|
||||
return false, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return v == 1, nil
|
||||
}
|
||||
|
||||
func setIPv6MulticastLoopback(fd syscall.Handle, v bool) error {
|
||||
vv := int32(boolint(v))
|
||||
return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastLoopback, (*byte)(unsafe.Pointer(&vv)), 4))
|
||||
}
|
||||
|
||||
func joinIPv6Group(fd syscall.Handle, ifi *net.Interface, grp net.IP) error {
|
||||
mreq := sysMulticastReq{}
|
||||
copy(mreq.IP[:], grp)
|
||||
if ifi != nil {
|
||||
mreq.IfIndex = uint32(ifi.Index)
|
||||
}
|
||||
return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIPv6, sysSockoptJoinGroup, (*byte)(unsafe.Pointer(&mreq)), int32(sysSizeofMulticastReq)))
|
||||
}
|
||||
|
||||
func leaveIPv6Group(fd syscall.Handle, ifi *net.Interface, grp net.IP) error {
|
||||
mreq := sysMulticastReq{}
|
||||
copy(mreq.IP[:], grp)
|
||||
if ifi != nil {
|
||||
mreq.IfIndex = uint32(ifi.Index)
|
||||
}
|
||||
return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIPv6, sysSockoptLeaveGroup, (*byte)(unsafe.Pointer(&mreq)), int32(sysSizeofMulticastReq)))
|
||||
}
|
||||
|
||||
func setIPv6Checksum(fd syscall.Handle, on bool, offset int) error {
|
||||
// TODO(mikio): Implement this
|
||||
return syscall.EWINDOWS
|
||||
}
|
||||
12
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3542_stub.go
generated
vendored
12
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3542_stub.go
generated
vendored
@@ -1,12 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build dragonfly plan9 solaris
|
||||
|
||||
package ipv6
|
||||
|
||||
func ipv6PathMTU(fd int) (int, error) {
|
||||
// TODO(mikio): Implement this
|
||||
return 0, errOpNoSupport
|
||||
}
|
||||
90
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3542_unix.go
generated
vendored
90
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3542_unix.go
generated
vendored
@@ -1,90 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build freebsd linux netbsd openbsd
|
||||
|
||||
package ipv6
|
||||
|
||||
import (
|
||||
"os"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func ipv6ReceiveTrafficClass(fd int) (bool, error) {
|
||||
var v int32
|
||||
l := sysSockoptLen(4)
|
||||
if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptReceiveTrafficClass, uintptr(unsafe.Pointer(&v)), &l); err != nil {
|
||||
return false, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return v == 1, nil
|
||||
}
|
||||
|
||||
func setIPv6ReceiveTrafficClass(fd int, v bool) error {
|
||||
vv := int32(boolint(v))
|
||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptReceiveTrafficClass, uintptr(unsafe.Pointer(&vv)), 4))
|
||||
}
|
||||
|
||||
func ipv6ReceiveHopLimit(fd int) (bool, error) {
|
||||
var v int32
|
||||
l := sysSockoptLen(4)
|
||||
if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptReceiveHopLimit, uintptr(unsafe.Pointer(&v)), &l); err != nil {
|
||||
return false, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return v == 1, nil
|
||||
}
|
||||
|
||||
func setIPv6ReceiveHopLimit(fd int, v bool) error {
|
||||
vv := int32(boolint(v))
|
||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptReceiveHopLimit, uintptr(unsafe.Pointer(&vv)), 4))
|
||||
}
|
||||
|
||||
func ipv6ReceivePacketInfo(fd int) (bool, error) {
|
||||
var v int32
|
||||
l := sysSockoptLen(4)
|
||||
if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptReceivePacketInfo, uintptr(unsafe.Pointer(&v)), &l); err != nil {
|
||||
return false, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return v == 1, nil
|
||||
}
|
||||
|
||||
func setIPv6ReceivePacketInfo(fd int, v bool) error {
|
||||
vv := int32(boolint(v))
|
||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptReceivePacketInfo, uintptr(unsafe.Pointer(&vv)), 4))
|
||||
}
|
||||
|
||||
func ipv6PathMTU(fd int) (int, error) {
|
||||
var v sysMTUInfo
|
||||
l := sysSockoptLen(sysSizeofMTUInfo)
|
||||
if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptPathMTU, uintptr(unsafe.Pointer(&v)), &l); err != nil {
|
||||
return 0, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return int(v.MTU), nil
|
||||
}
|
||||
|
||||
func ipv6ReceivePathMTU(fd int) (bool, error) {
|
||||
var v int32
|
||||
l := sysSockoptLen(4)
|
||||
if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptReceivePathMTU, uintptr(unsafe.Pointer(&v)), &l); err != nil {
|
||||
return false, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return v == 1, nil
|
||||
}
|
||||
|
||||
func setIPv6ReceivePathMTU(fd int, v bool) error {
|
||||
vv := int32(boolint(v))
|
||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptReceivePathMTU, uintptr(unsafe.Pointer(&vv)), 4))
|
||||
}
|
||||
|
||||
func ipv6ICMPFilter(fd int) (*ICMPFilter, error) {
|
||||
var v ICMPFilter
|
||||
l := sysSockoptLen(sysSizeofICMPFilter)
|
||||
if err := getsockopt(fd, ianaProtocolIPv6ICMP, sysSockoptICMPFilter, uintptr(unsafe.Pointer(&v.sysICMPFilter)), &l); err != nil {
|
||||
return nil, os.NewSyscallError("getsockopt", err)
|
||||
}
|
||||
return &v, nil
|
||||
}
|
||||
|
||||
func setIPv6ICMPFilter(fd int, f *ICMPFilter) error {
|
||||
return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6ICMP, sysSockoptICMPFilter, uintptr(unsafe.Pointer(&f.sysICMPFilter)), sysSizeofICMPFilter))
|
||||
}
|
||||
62
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3542_windows.go
generated
vendored
62
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_rfc3542_windows.go
generated
vendored
@@ -1,62 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6
|
||||
|
||||
import "syscall"
|
||||
|
||||
func ipv6ReceiveTrafficClass(fd syscall.Handle) (bool, error) {
|
||||
// TODO(mikio): Implement this
|
||||
return false, syscall.EWINDOWS
|
||||
}
|
||||
|
||||
func setIPv6ReceiveTrafficClass(fd syscall.Handle, v bool) error {
|
||||
// TODO(mikio): Implement this
|
||||
return syscall.EWINDOWS
|
||||
}
|
||||
|
||||
func ipv6ReceiveHopLimit(fd syscall.Handle) (bool, error) {
|
||||
// TODO(mikio): Implement this
|
||||
return false, syscall.EWINDOWS
|
||||
}
|
||||
|
||||
func setIPv6ReceiveHopLimit(fd syscall.Handle, v bool) error {
|
||||
// TODO(mikio): Implement this
|
||||
return syscall.EWINDOWS
|
||||
}
|
||||
|
||||
func ipv6ReceivePacketInfo(fd syscall.Handle) (bool, error) {
|
||||
// TODO(mikio): Implement this
|
||||
return false, syscall.EWINDOWS
|
||||
}
|
||||
|
||||
func setIPv6ReceivePacketInfo(fd syscall.Handle, v bool) error {
|
||||
// TODO(mikio): Implement this
|
||||
return syscall.EWINDOWS
|
||||
}
|
||||
|
||||
func ipv6PathMTU(fd syscall.Handle) (int, error) {
|
||||
// TODO(mikio): Implement this
|
||||
return 0, syscall.EWINDOWS
|
||||
}
|
||||
|
||||
func ipv6ReceivePathMTU(fd syscall.Handle) (bool, error) {
|
||||
// TODO(mikio): Implement this
|
||||
return false, syscall.EWINDOWS
|
||||
}
|
||||
|
||||
func setIPv6ReceivePathMTU(fd syscall.Handle, v bool) error {
|
||||
// TODO(mikio): Implement this
|
||||
return syscall.EWINDOWS
|
||||
}
|
||||
|
||||
func ipv6ICMPFilter(fd syscall.Handle) (*ICMPFilter, error) {
|
||||
// TODO(mikio): Implement this
|
||||
return nil, syscall.EWINDOWS
|
||||
}
|
||||
|
||||
func setIPv6ICMPFilter(fd syscall.Handle, f *ICMPFilter) error {
|
||||
// TODO(mikio): Implement this
|
||||
return syscall.EWINDOWS
|
||||
}
|
||||
136
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_test.go
generated
vendored
136
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sockopt_test.go
generated
vendored
@@ -1,136 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6_test
|
||||
|
||||
import (
|
||||
"code.google.com/p/go.net/ipv6"
|
||||
"net"
|
||||
"os"
|
||||
"runtime"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var supportsIPv6 bool
|
||||
|
||||
func init() {
|
||||
if ln, err := net.Listen("tcp6", "[::1]:0"); err == nil {
|
||||
ln.Close()
|
||||
supportsIPv6 = true
|
||||
}
|
||||
}
|
||||
|
||||
var condFatalf = func() func(*testing.T, string, ...interface{}) {
|
||||
// A few APIs are not implemented yet on some platforms.
|
||||
switch runtime.GOOS {
|
||||
case "darwin", "dragonfly", "plan9", "solaris", "windows":
|
||||
return (*testing.T).Logf
|
||||
}
|
||||
return (*testing.T).Fatalf
|
||||
}()
|
||||
|
||||
func TestConnInitiatorPathMTU(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "dragonfly", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %q", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
t.Skip("ipv6 is not supported")
|
||||
}
|
||||
|
||||
ln, err := net.Listen("tcp6", "[::1]:0")
|
||||
if err != nil {
|
||||
t.Fatalf("net.Listen failed: %v", err)
|
||||
}
|
||||
defer ln.Close()
|
||||
|
||||
done := make(chan bool)
|
||||
go acceptor(t, ln, done)
|
||||
|
||||
c, err := net.Dial("tcp6", ln.Addr().String())
|
||||
if err != nil {
|
||||
t.Fatalf("net.Dial failed: %v", err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
if pmtu, err := ipv6.NewConn(c).PathMTU(); err != nil {
|
||||
condFatalf(t, "ipv6.Conn.PathMTU failed: %v", err)
|
||||
} else {
|
||||
t.Logf("path mtu for %v: %v", c.RemoteAddr(), pmtu)
|
||||
}
|
||||
|
||||
<-done
|
||||
}
|
||||
|
||||
func TestConnResponderPathMTU(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "dragonfly", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %q", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
t.Skip("ipv6 is not supported")
|
||||
}
|
||||
|
||||
ln, err := net.Listen("tcp6", "[::1]:0")
|
||||
if err != nil {
|
||||
t.Fatalf("net.Listen failed: %v", err)
|
||||
}
|
||||
defer ln.Close()
|
||||
|
||||
done := make(chan bool)
|
||||
go connector(t, "tcp6", ln.Addr().String(), done)
|
||||
|
||||
c, err := ln.Accept()
|
||||
if err != nil {
|
||||
t.Fatalf("net.Accept failed: %v", err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
if pmtu, err := ipv6.NewConn(c).PathMTU(); err != nil {
|
||||
condFatalf(t, "ipv6.Conn.PathMTU failed: %v", err)
|
||||
} else {
|
||||
t.Logf("path mtu for %v: %v", c.RemoteAddr(), pmtu)
|
||||
}
|
||||
|
||||
<-done
|
||||
}
|
||||
|
||||
func TestPacketConnChecksum(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "dragonfly", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %q", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
t.Skip("ipv6 is not supported")
|
||||
}
|
||||
if os.Getuid() != 0 {
|
||||
t.Skip("must be root")
|
||||
}
|
||||
|
||||
c, err := net.ListenPacket("ip6:89", "::") // OSPF for IPv6
|
||||
if err != nil {
|
||||
t.Fatalf("net.ListenPacket failed: %v", err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
p := ipv6.NewPacketConn(c)
|
||||
offset := 12 // see RFC 5340
|
||||
|
||||
for _, toggle := range []bool{false, true} {
|
||||
if err := p.SetChecksum(toggle, offset); err != nil {
|
||||
if toggle {
|
||||
t.Fatalf("ipv6.PacketConn.SetChecksum(%v, %v) failed: %v", toggle, offset, err)
|
||||
} else {
|
||||
// Some platforms never allow to disable the kernel
|
||||
// checksum processing.
|
||||
t.Logf("ipv6.PacketConn.SetChecksum(%v, %v) failed: %v", toggle, offset, err)
|
||||
}
|
||||
}
|
||||
if on, offset, err := p.Checksum(); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.Checksum failed: %v", err)
|
||||
} else {
|
||||
t.Logf("kernel checksum processing enabled=%v, offset=%v", on, offset)
|
||||
}
|
||||
}
|
||||
}
|
||||
23
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sys.go
generated
vendored
23
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sys.go
generated
vendored
@@ -1,23 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6
|
||||
|
||||
type sysSockoptLen uint32
|
||||
|
||||
const (
|
||||
sysSizeofPacketInfo = 0x14
|
||||
sysSizeofMulticastReq = 0x14
|
||||
sysSizeofICMPFilter = 0x20
|
||||
)
|
||||
|
||||
type sysPacketInfo struct {
|
||||
IP [16]byte
|
||||
IfIndex uint32
|
||||
}
|
||||
|
||||
type sysMulticastReq struct {
|
||||
IP [16]byte
|
||||
IfIndex uint32
|
||||
}
|
||||
48
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sys_bsd.go
generated
vendored
48
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sys_bsd.go
generated
vendored
@@ -1,48 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build freebsd netbsd openbsd
|
||||
|
||||
package ipv6
|
||||
|
||||
import (
|
||||
"net"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// RFC 3493 options
|
||||
const (
|
||||
// See /usr/include/netinet6/in6.h.
|
||||
sysSockoptUnicastHopLimit = 0x4
|
||||
sysSockoptMulticastHopLimit = 0xa
|
||||
sysSockoptMulticastInterface = 0x9
|
||||
sysSockoptMulticastLoopback = 0xb
|
||||
sysSockoptJoinGroup = 0xc
|
||||
sysSockoptLeaveGroup = 0xd
|
||||
)
|
||||
|
||||
// RFC 3542 options
|
||||
const (
|
||||
// See /usr/include/netinet6/in6.h.
|
||||
sysSockoptReceiveTrafficClass = 0x39
|
||||
sysSockoptTrafficClass = 0x3d
|
||||
sysSockoptReceiveHopLimit = 0x25
|
||||
sysSockoptHopLimit = 0x2f
|
||||
sysSockoptReceivePacketInfo = 0x24
|
||||
sysSockoptPacketInfo = 0x2e
|
||||
sysSockoptReceivePathMTU = 0x2b
|
||||
sysSockoptPathMTU = 0x2c
|
||||
sysSockoptNextHop = 0x30
|
||||
sysSockoptChecksum = 0x1a
|
||||
|
||||
// See /usr/include/netinet6/in6.h.
|
||||
sysSockoptICMPFilter = 0x12
|
||||
)
|
||||
|
||||
func setSockaddr(sa *syscall.RawSockaddrInet6, ip net.IP, ifindex int) {
|
||||
sa.Len = syscall.SizeofSockaddrInet6
|
||||
sa.Family = syscall.AF_INET6
|
||||
copy(sa.Addr[:], ip)
|
||||
sa.Scope_id = uint32(ifindex)
|
||||
}
|
||||
54
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sys_darwin.go
generated
vendored
54
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sys_darwin.go
generated
vendored
@@ -1,54 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6
|
||||
|
||||
import (
|
||||
"net"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// RFC 2292 options
|
||||
const (
|
||||
// See /usr/include/netinet6/in6.h.
|
||||
sysSockopt2292HopLimit = 0x14
|
||||
sysSockopt2292PacketInfo = 0x13
|
||||
sysSockopt2292NextHop = 0x15
|
||||
)
|
||||
|
||||
// RFC 3493 options
|
||||
const (
|
||||
// See /usr/include/netinet6/in6.h.
|
||||
sysSockoptUnicastHopLimit = 0x4
|
||||
sysSockoptMulticastHopLimit = 0xa
|
||||
sysSockoptMulticastInterface = 0x9
|
||||
sysSockoptMulticastLoopback = 0xb
|
||||
sysSockoptJoinGroup = 0xc
|
||||
sysSockoptLeaveGroup = 0xd
|
||||
)
|
||||
|
||||
// RFC 3542 options
|
||||
const (
|
||||
// See /usr/include/netinet6/in6.h.
|
||||
sysSockoptReceiveTrafficClass = 0x23
|
||||
sysSockoptTrafficClass = 0x24
|
||||
sysSockoptReceiveHopLimit = 0x25
|
||||
sysSockoptHopLimit = 0x2f
|
||||
sysSockoptReceivePacketInfo = 0x3d
|
||||
sysSockoptPacketInfo = 0x2e
|
||||
sysSockoptReceivePathMTU = 0x2b
|
||||
sysSockoptPathMTU = 0x2c
|
||||
sysSockoptNextHop = 0x30
|
||||
sysSockoptChecksum = 0x1a
|
||||
|
||||
// See /usr/include/netinet6/in6.h.
|
||||
sysSockoptICMPFilter = 0x12
|
||||
)
|
||||
|
||||
func setSockaddr(sa *syscall.RawSockaddrInet6, ip net.IP, ifindex int) {
|
||||
sa.Len = syscall.SizeofSockaddrInet6
|
||||
sa.Family = syscall.AF_INET6
|
||||
copy(sa.Addr[:], ip)
|
||||
sa.Scope_id = uint32(ifindex)
|
||||
}
|
||||
45
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sys_linux.go
generated
vendored
45
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sys_linux.go
generated
vendored
@@ -1,45 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6
|
||||
|
||||
import (
|
||||
"net"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// RFC 3493 options
|
||||
const (
|
||||
// See /usr/include/linux/in6.h.
|
||||
sysSockoptUnicastHopLimit = 0x10
|
||||
sysSockoptMulticastHopLimit = 0x12
|
||||
sysSockoptMulticastInterface = 0x11
|
||||
sysSockoptMulticastLoopback = 0x13
|
||||
sysSockoptJoinGroup = 0x14
|
||||
sysSockoptLeaveGroup = 0x15
|
||||
)
|
||||
|
||||
// RFC 3542 options
|
||||
const (
|
||||
// See /usr/include/linux/ipv6.h,in6.h.
|
||||
sysSockoptReceiveTrafficClass = 0x42
|
||||
sysSockoptTrafficClass = 0x43
|
||||
sysSockoptReceiveHopLimit = 0x33
|
||||
sysSockoptHopLimit = 0x34
|
||||
sysSockoptReceivePacketInfo = 0x31
|
||||
sysSockoptPacketInfo = 0x32
|
||||
sysSockoptReceivePathMTU = 0x3c
|
||||
sysSockoptPathMTU = 0x3d
|
||||
sysSockoptNextHop = 0x9
|
||||
sysSockoptChecksum = 0x7
|
||||
|
||||
// See /usr/include/linux/icmpv6.h.
|
||||
sysSockoptICMPFilter = 0x1
|
||||
)
|
||||
|
||||
func setSockaddr(sa *syscall.RawSockaddrInet6, ip net.IP, ifindex int) {
|
||||
sa.Family = syscall.AF_INET6
|
||||
copy(sa.Addr[:], ip)
|
||||
sa.Scope_id = uint32(ifindex)
|
||||
}
|
||||
16
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sys_unix.go
generated
vendored
16
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sys_unix.go
generated
vendored
@@ -1,16 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build darwin freebsd linux netbsd openbsd
|
||||
|
||||
package ipv6
|
||||
|
||||
import "syscall"
|
||||
|
||||
const sysSizeofMTUInfo = 0x20
|
||||
|
||||
type sysMTUInfo struct {
|
||||
Addr syscall.RawSockaddrInet6
|
||||
MTU uint32
|
||||
}
|
||||
33
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sys_windows.go
generated
vendored
33
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/sys_windows.go
generated
vendored
@@ -1,33 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6
|
||||
|
||||
import (
|
||||
"net"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// RFC 3493 options
|
||||
const (
|
||||
// See ws2tcpip.h.
|
||||
sysSockoptUnicastHopLimit = 0x4
|
||||
sysSockoptMulticastHopLimit = 0xa
|
||||
sysSockoptMulticastInterface = 0x9
|
||||
sysSockoptMulticastLoopback = 0xb
|
||||
sysSockoptJoinGroup = 0xc
|
||||
sysSockoptLeaveGroup = 0xd
|
||||
)
|
||||
|
||||
// RFC 3542 options
|
||||
const (
|
||||
// See ws2tcpip.h.
|
||||
sysSockoptPacketInfo = 0x13
|
||||
)
|
||||
|
||||
func setSockaddr(sa *syscall.RawSockaddrInet6, ip net.IP, ifindex int) {
|
||||
sa.Family = syscall.AF_INET6
|
||||
copy(sa.Addr[:], ip)
|
||||
sa.Scope_id = uint32(ifindex)
|
||||
}
|
||||
42
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/syscall_linux_386.go
generated
vendored
42
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/syscall_linux_386.go
generated
vendored
@@ -1,42 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// This code is a duplicate of syscall/syscall_linux_386.go with small
|
||||
// modifications.
|
||||
|
||||
package ipv6
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// On x86 Linux, all the socket calls go through an extra indirection,
|
||||
// I think because the 5-register system call interface can't handle
|
||||
// the 6-argument calls like sendto and recvfrom. Instead the
|
||||
// arguments to the underlying system call are the number below and a
|
||||
// pointer to an array of uintptr. We hide the pointer in the
|
||||
// socketcall assembly to avoid allocation on every system call.
|
||||
|
||||
const (
|
||||
// See /usr/include/linux/net.h.
|
||||
_SETSOCKOPT = 14
|
||||
_GETSOCKOPT = 15
|
||||
)
|
||||
|
||||
var socketcall func(call int, a0, a1, a2, a3, a4, a5 uintptr) (int, syscall.Errno)
|
||||
|
||||
func getsockopt(fd int, level int, name int, v uintptr, l *sysSockoptLen) error {
|
||||
if _, errno := socketcall(_GETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(v), uintptr(unsafe.Pointer(l)), 0); errno != 0 {
|
||||
return error(errno)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func setsockopt(fd int, level int, name int, v uintptr, l uintptr) error {
|
||||
if _, errno := socketcall(_SETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), v, l, 0); errno != 0 {
|
||||
return error(errno)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
56
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/syscall_linux_386.s
generated
vendored
56
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/syscall_linux_386.s
generated
vendored
@@ -1,56 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// This code is a duplicate of syscall/syscall_linux_386.s with small
|
||||
// modifications.
|
||||
|
||||
#define SYS_SOCKETCALL 102 // from zsysnum_linux_386.go
|
||||
|
||||
// func socketcallnosplit7(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, errno int)
|
||||
// Kernel interface gets call sub-number and pointer to a0 for Go 1.1.
|
||||
TEXT ·socketcallnosplit7(SB),7,$0
|
||||
CALL runtime·entersyscall(SB)
|
||||
MOVL $SYS_SOCKETCALL, AX // syscall entry
|
||||
MOVL 4(SP), BX // socket call number
|
||||
LEAL 8(SP), CX // pointer to call arguments
|
||||
MOVL $0, DX
|
||||
MOVL $0, SI
|
||||
MOVL $0, DI
|
||||
CALL *runtime·_vdso(SB)
|
||||
CMPL AX, $0xfffff001
|
||||
JLS ok1
|
||||
MOVL $-1, 32(SP) // n
|
||||
NEGL AX
|
||||
MOVL AX, 36(SP) // errno
|
||||
CALL runtime·exitsyscall(SB)
|
||||
RET
|
||||
ok1:
|
||||
MOVL AX, 32(SP) // n
|
||||
MOVL $0, 36(SP) // errno
|
||||
CALL runtime·exitsyscall(SB)
|
||||
RET
|
||||
|
||||
// func socketcallnosplit4(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, errno int)
|
||||
// Kernel interface gets call sub-number and pointer to a0 for Go 1.2.
|
||||
TEXT ·socketcallnosplit4(SB),4,$0-40
|
||||
CALL runtime·entersyscall(SB)
|
||||
MOVL $SYS_SOCKETCALL, AX // syscall entry
|
||||
MOVL 4(SP), BX // socket call number
|
||||
LEAL 8(SP), CX // pointer to call arguments
|
||||
MOVL $0, DX
|
||||
MOVL $0, SI
|
||||
MOVL $0, DI
|
||||
CALL *runtime·_vdso(SB)
|
||||
CMPL AX, $0xfffff001
|
||||
JLS ok2
|
||||
MOVL $-1, 32(SP) // n
|
||||
NEGL AX
|
||||
MOVL AX, 36(SP) // errno
|
||||
CALL runtime·exitsyscall(SB)
|
||||
RET
|
||||
ok2:
|
||||
MOVL AX, 32(SP) // n
|
||||
MOVL $0, 36(SP) // errno
|
||||
CALL runtime·exitsyscall(SB)
|
||||
RET
|
||||
15
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/syscall_nosplit4_linux_386.go
generated
vendored
15
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/syscall_nosplit4_linux_386.go
generated
vendored
@@ -1,15 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build go1.2
|
||||
|
||||
package ipv6
|
||||
|
||||
import "syscall"
|
||||
|
||||
func socketcallnosplit4(call int, a0, a1, a2, a3, a4, a5 uintptr) (int, syscall.Errno)
|
||||
|
||||
func init() {
|
||||
socketcall = socketcallnosplit4
|
||||
}
|
||||
15
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/syscall_nosplit7_linux_386.go
generated
vendored
15
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/syscall_nosplit7_linux_386.go
generated
vendored
@@ -1,15 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build go1.1,!go1.2
|
||||
|
||||
package ipv6
|
||||
|
||||
import "syscall"
|
||||
|
||||
func socketcallnosplit7(call int, a0, a1, a2, a3, a4, a5 uintptr) (int, syscall.Errno)
|
||||
|
||||
func init() {
|
||||
socketcall = socketcallnosplit7
|
||||
}
|
||||
26
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/syscall_unix.go
generated
vendored
26
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/syscall_unix.go
generated
vendored
@@ -1,26 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build darwin freebsd linux,amd64 linux,arm netbsd openbsd
|
||||
|
||||
package ipv6
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func getsockopt(fd int, level, name int, v uintptr, l *sysSockoptLen) error {
|
||||
if _, _, errno := syscall.Syscall6(syscall.SYS_GETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(v), uintptr(unsafe.Pointer(l)), 0); errno != 0 {
|
||||
return error(errno)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func setsockopt(fd int, level int, name int, v uintptr, l uintptr) error {
|
||||
if _, _, errno := syscall.Syscall6(syscall.SYS_SETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(v), uintptr(l), 0); errno != 0 {
|
||||
return error(errno)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
172
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/unicast_test.go
generated
vendored
172
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/unicast_test.go
generated
vendored
@@ -1,172 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"code.google.com/p/go.net/ipv6"
|
||||
"net"
|
||||
"os"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestPacketConnReadWriteUnicastUDP(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "dragonfly", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %q", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
t.Skip("ipv6 is not supported")
|
||||
}
|
||||
|
||||
c, err := net.ListenPacket("udp6", "[::1]:0")
|
||||
if err != nil {
|
||||
t.Fatalf("net.ListenPacket failed: %v", err)
|
||||
}
|
||||
defer c.Close()
|
||||
p := ipv6.NewPacketConn(c)
|
||||
defer p.Close()
|
||||
|
||||
dst, err := net.ResolveUDPAddr("udp6", c.LocalAddr().String())
|
||||
if err != nil {
|
||||
t.Fatalf("net.ResolveUDPAddr failed: %v", err)
|
||||
}
|
||||
|
||||
cm := ipv6.ControlMessage{
|
||||
TrafficClass: DiffServAF11 | CongestionExperienced,
|
||||
Src: net.IPv6loopback,
|
||||
Dst: net.IPv6loopback,
|
||||
}
|
||||
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
|
||||
ifi := loopbackInterface()
|
||||
if ifi != nil {
|
||||
cm.IfIndex = ifi.Index
|
||||
}
|
||||
wb := []byte("HELLO-R-U-THERE")
|
||||
|
||||
for i, toggle := range []bool{true, false, true} {
|
||||
if err := p.SetControlMessage(cf, toggle); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.SetControlMessage failed: %v", err)
|
||||
}
|
||||
cm.HopLimit = i + 1
|
||||
if err := p.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.SetWriteDeadline failed: %v", err)
|
||||
}
|
||||
if n, err := p.WriteTo(wb, &cm, dst); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.WriteTo failed: %v", err)
|
||||
} else if n != len(wb) {
|
||||
t.Fatalf("ipv6.PacketConn.WriteTo failed: short write: %v", n)
|
||||
}
|
||||
rb := make([]byte, 128)
|
||||
if err := p.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.SetReadDeadline failed: %v", err)
|
||||
}
|
||||
if n, cm, _, err := p.ReadFrom(rb); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.ReadFrom failed: %v", err)
|
||||
} else if !bytes.Equal(rb[:n], wb) {
|
||||
t.Fatalf("got %v; expected %v", rb[:n], wb)
|
||||
} else {
|
||||
t.Logf("rcvd cmsg: %v", cm)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPacketConnReadWriteUnicastICMP(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "dragonfly", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %q", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
t.Skip("ipv6 is not supported")
|
||||
}
|
||||
if os.Getuid() != 0 {
|
||||
t.Skip("must be root")
|
||||
}
|
||||
|
||||
c, err := net.ListenPacket("ip6:ipv6-icmp", "::1")
|
||||
if err != nil {
|
||||
t.Fatalf("net.ListenPacket failed: %v", err)
|
||||
}
|
||||
defer c.Close()
|
||||
p := ipv6.NewPacketConn(c)
|
||||
defer p.Close()
|
||||
|
||||
dst, err := net.ResolveIPAddr("ip6", "::1")
|
||||
if err != nil {
|
||||
t.Fatalf("net.ResolveIPAddr failed: %v", err)
|
||||
}
|
||||
|
||||
pshicmp := ipv6PseudoHeader(c.LocalAddr().(*net.IPAddr).IP, dst.IP, ianaProtocolIPv6ICMP)
|
||||
cm := ipv6.ControlMessage{
|
||||
TrafficClass: DiffServAF11 | CongestionExperienced,
|
||||
Src: net.IPv6loopback,
|
||||
Dst: net.IPv6loopback,
|
||||
}
|
||||
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
|
||||
ifi := loopbackInterface()
|
||||
if ifi != nil {
|
||||
cm.IfIndex = ifi.Index
|
||||
}
|
||||
|
||||
var f ipv6.ICMPFilter
|
||||
f.SetAll(true)
|
||||
f.Set(ipv6.ICMPTypeEchoReply, false)
|
||||
if err := p.SetICMPFilter(&f); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.SetICMPFilter failed: %v", err)
|
||||
}
|
||||
|
||||
var psh []byte
|
||||
for i, toggle := range []bool{true, false, true} {
|
||||
if toggle {
|
||||
psh = nil
|
||||
if err := p.SetChecksum(true, 2); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.SetChecksum failed: %v", err)
|
||||
}
|
||||
} else {
|
||||
psh = pshicmp
|
||||
// Some platforms never allow to disable the
|
||||
// kernel checksum processing.
|
||||
p.SetChecksum(false, -1)
|
||||
}
|
||||
wb, err := (&icmpMessage{
|
||||
Type: ipv6.ICMPTypeEchoRequest, Code: 0,
|
||||
Body: &icmpEcho{
|
||||
ID: os.Getpid() & 0xffff, Seq: i + 1,
|
||||
Data: []byte("HELLO-R-U-THERE"),
|
||||
},
|
||||
}).Marshal(psh)
|
||||
if err != nil {
|
||||
t.Fatalf("icmpMessage.Marshal failed: %v", err)
|
||||
}
|
||||
if err := p.SetControlMessage(cf, toggle); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.SetControlMessage failed: %v", err)
|
||||
}
|
||||
cm.HopLimit = i + 1
|
||||
if err := p.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.SetWriteDeadline failed: %v", err)
|
||||
}
|
||||
if n, err := p.WriteTo(wb, &cm, dst); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.WriteTo failed: %v", err)
|
||||
} else if n != len(wb) {
|
||||
t.Fatalf("ipv6.PacketConn.WriteTo failed: short write: %v", n)
|
||||
}
|
||||
rb := make([]byte, 128)
|
||||
if err := p.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.SetReadDeadline failed: %v", err)
|
||||
}
|
||||
if n, cm, _, err := p.ReadFrom(rb); err != nil {
|
||||
t.Fatalf("ipv6.PacketConn.ReadFrom failed: %v", err)
|
||||
} else {
|
||||
t.Logf("rcvd cmsg: %v", cm)
|
||||
if m, err := parseICMPMessage(rb[:n]); err != nil {
|
||||
t.Fatalf("parseICMPMessage failed: %v", err)
|
||||
} else if m.Type != ipv6.ICMPTypeEchoReply || m.Code != 0 {
|
||||
t.Fatalf("got type=%v, code=%v; expected type=%v, code=%v", m.Type, m.Code, ipv6.ICMPTypeEchoReply, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
101
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/unicastsockopt_test.go
generated
vendored
101
Godeps/_workspace/src/code.google.com/p/go.net/ipv6/unicastsockopt_test.go
generated
vendored
@@ -1,101 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv6_test
|
||||
|
||||
import (
|
||||
"code.google.com/p/go.net/ipv6"
|
||||
"net"
|
||||
"os"
|
||||
"runtime"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestConnUnicastSocketOptions(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "dragonfly", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %q", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
t.Skip("ipv6 is not supported")
|
||||
}
|
||||
|
||||
ln, err := net.Listen("tcp6", "[::1]:0")
|
||||
if err != nil {
|
||||
t.Fatalf("net.Listen failed: %v", err)
|
||||
}
|
||||
defer ln.Close()
|
||||
|
||||
done := make(chan bool)
|
||||
go acceptor(t, ln, done)
|
||||
|
||||
c, err := net.Dial("tcp6", ln.Addr().String())
|
||||
if err != nil {
|
||||
t.Fatalf("net.Dial failed: %v", err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
testUnicastSocketOptions(t, ipv6.NewConn(c))
|
||||
|
||||
<-done
|
||||
}
|
||||
|
||||
var packetConnUnicastSocketOptionTests = []struct {
|
||||
net, proto, addr string
|
||||
}{
|
||||
{"udp6", "", "[::1]:0"},
|
||||
{"ip6", ":ipv6-icmp", "::1"},
|
||||
}
|
||||
|
||||
func TestPacketConnUnicastSocketOptions(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "dragonfly", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %q", runtime.GOOS)
|
||||
}
|
||||
if !supportsIPv6 {
|
||||
t.Skip("ipv6 is not supported")
|
||||
}
|
||||
|
||||
for _, tt := range packetConnUnicastSocketOptionTests {
|
||||
if tt.net == "ip6" && os.Getuid() != 0 {
|
||||
t.Skip("must be root")
|
||||
}
|
||||
c, err := net.ListenPacket(tt.net+tt.proto, tt.addr)
|
||||
if err != nil {
|
||||
t.Fatalf("net.ListenPacket(%q, %q) failed: %v", tt.net+tt.proto, tt.addr, err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
testUnicastSocketOptions(t, ipv6.NewPacketConn(c))
|
||||
}
|
||||
}
|
||||
|
||||
type testIPv6UnicastConn interface {
|
||||
TrafficClass() (int, error)
|
||||
SetTrafficClass(int) error
|
||||
HopLimit() (int, error)
|
||||
SetHopLimit(int) error
|
||||
}
|
||||
|
||||
func testUnicastSocketOptions(t *testing.T, c testIPv6UnicastConn) {
|
||||
tclass := DiffServCS0 | NotECNTransport
|
||||
if err := c.SetTrafficClass(tclass); err != nil {
|
||||
t.Fatalf("ipv6.Conn.SetTrafficClass failed: %v", err)
|
||||
}
|
||||
if v, err := c.TrafficClass(); err != nil {
|
||||
t.Fatalf("ipv6.Conn.TrafficClass failed: %v", err)
|
||||
} else if v != tclass {
|
||||
t.Fatalf("got unexpected traffic class %v; expected %v", v, tclass)
|
||||
}
|
||||
|
||||
hoplim := 255
|
||||
if err := c.SetHopLimit(hoplim); err != nil {
|
||||
t.Fatalf("ipv6.Conn.SetHopLimit failed: %v", err)
|
||||
}
|
||||
if v, err := c.HopLimit(); err != nil {
|
||||
t.Fatalf("ipv6.Conn.HopLimit failed: %v", err)
|
||||
} else if v != hoplim {
|
||||
t.Fatalf("got unexpected hop limit %v; expected %v", v, hoplim)
|
||||
}
|
||||
}
|
||||
146
Godeps/_workspace/src/code.google.com/p/go.text/transform/transform.go
generated
vendored
146
Godeps/_workspace/src/code.google.com/p/go.text/transform/transform.go
generated
vendored
@@ -9,6 +9,7 @@
|
||||
package transform
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
"unicode/utf8"
|
||||
@@ -127,7 +128,7 @@ func (r *Reader) Read(p []byte) (int, error) {
|
||||
// cannot read more bytes into src.
|
||||
r.transformComplete = r.err != nil
|
||||
continue
|
||||
case err == ErrShortDst && r.dst1 != 0:
|
||||
case err == ErrShortDst && (r.dst1 != 0 || n != 0):
|
||||
// Make room in dst by copying out, and try again.
|
||||
continue
|
||||
case err == ErrShortSrc && r.src1-r.src0 != len(r.src) && r.err == nil:
|
||||
@@ -210,7 +211,7 @@ func (w *Writer) Write(data []byte) (n int, err error) {
|
||||
n += nSrc
|
||||
}
|
||||
switch {
|
||||
case err == ErrShortDst && nDst > 0:
|
||||
case err == ErrShortDst && (nDst > 0 || nSrc > 0):
|
||||
case err == ErrShortSrc && len(src) < len(w.src):
|
||||
m := copy(w.src, src)
|
||||
// If w.n > 0, bytes from data were already copied to w.src and n
|
||||
@@ -467,30 +468,125 @@ func (t removeF) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err err
|
||||
return
|
||||
}
|
||||
|
||||
// Bytes returns a new byte slice with the result of converting b using t.
|
||||
// If any unrecoverable error occurs it returns nil.
|
||||
func Bytes(t Transformer, b []byte) []byte {
|
||||
out := make([]byte, len(b))
|
||||
n := 0
|
||||
for {
|
||||
nDst, nSrc, err := t.Transform(out[n:], b, true)
|
||||
n += nDst
|
||||
if err == nil {
|
||||
return out[:n]
|
||||
} else if err != ErrShortDst {
|
||||
return nil
|
||||
}
|
||||
b = b[nSrc:]
|
||||
// grow returns a new []byte that is longer than b, and copies the first n bytes
|
||||
// of b to the start of the new slice.
|
||||
func grow(b []byte, n int) []byte {
|
||||
m := len(b)
|
||||
if m <= 256 {
|
||||
m *= 2
|
||||
} else {
|
||||
m += m >> 1
|
||||
}
|
||||
buf := make([]byte, m)
|
||||
copy(buf, b[:n])
|
||||
return buf
|
||||
}
|
||||
|
||||
// Grow the destination buffer.
|
||||
sz := len(out)
|
||||
if sz <= 256 {
|
||||
sz *= 2
|
||||
} else {
|
||||
sz += sz >> 1
|
||||
const initialBufSize = 128
|
||||
|
||||
// String returns a string with the result of converting s[:n] using t, where
|
||||
// n <= len(s). If err == nil, n will be len(s).
|
||||
func String(t Transformer, s string) (result string, n int, err error) {
|
||||
if s == "" {
|
||||
return "", 0, nil
|
||||
}
|
||||
|
||||
// Allocate only once. Note that both dst and src escape when passed to
|
||||
// Transform.
|
||||
buf := [2 * initialBufSize]byte{}
|
||||
dst := buf[:initialBufSize:initialBufSize]
|
||||
src := buf[initialBufSize : 2*initialBufSize]
|
||||
|
||||
// Avoid allocation if the transformed string is identical to the original.
|
||||
// After this loop, pDst will point to the furthest point in s for which it
|
||||
// could be detected that t gives equal results, src[:nSrc] will
|
||||
// indicated the last processed chunk of s for which the output is not equal
|
||||
// and dst[:nDst] will be the transform of this chunk.
|
||||
var nDst, nSrc int
|
||||
pDst := 0 // Used as index in both src and dst in this loop.
|
||||
for {
|
||||
n := copy(src, s[pDst:])
|
||||
nDst, nSrc, err = t.Transform(dst, src[:n], pDst+n == len(s))
|
||||
|
||||
// Note 1: we will not enter the loop with pDst == len(s) and we will
|
||||
// not end the loop with it either. So if nSrc is 0, this means there is
|
||||
// some kind of error from which we cannot recover given the current
|
||||
// buffer sizes. We will give up in this case.
|
||||
// Note 2: it is not entirely correct to simply do a bytes.Equal as
|
||||
// a Transformer may buffer internally. It will work in most cases,
|
||||
// though, and no harm is done if it doesn't work.
|
||||
// TODO: let transformers implement an optional Spanner interface, akin
|
||||
// to norm's QuickSpan. This would even allow us to avoid any allocation.
|
||||
if nSrc == 0 || !bytes.Equal(dst[:nDst], src[:nSrc]) {
|
||||
break
|
||||
}
|
||||
|
||||
if pDst += nDst; pDst == len(s) {
|
||||
return s, pDst, nil
|
||||
}
|
||||
}
|
||||
|
||||
// Move the bytes seen so far to dst.
|
||||
pSrc := pDst + nSrc
|
||||
if pDst+nDst <= initialBufSize {
|
||||
copy(dst[pDst:], dst[:nDst])
|
||||
} else {
|
||||
b := make([]byte, len(s)+nDst-nSrc)
|
||||
copy(b[pDst:], dst[:nDst])
|
||||
dst = b
|
||||
}
|
||||
copy(dst, s[:pDst])
|
||||
pDst += nDst
|
||||
|
||||
if err != nil && err != ErrShortDst && err != ErrShortSrc {
|
||||
return string(dst[:pDst]), pSrc, err
|
||||
}
|
||||
|
||||
// Complete the string with the remainder.
|
||||
for {
|
||||
n := copy(src, s[pSrc:])
|
||||
nDst, nSrc, err = t.Transform(dst[pDst:], src[:n], pSrc+n == len(s))
|
||||
pDst += nDst
|
||||
pSrc += nSrc
|
||||
|
||||
switch err {
|
||||
case nil:
|
||||
if pSrc == len(s) {
|
||||
return string(dst[:pDst]), pSrc, nil
|
||||
}
|
||||
case ErrShortDst:
|
||||
// Do not grow as long as we can make progress. This may avoid
|
||||
// excessive allocations.
|
||||
if nDst == 0 {
|
||||
dst = grow(dst, pDst)
|
||||
}
|
||||
case ErrShortSrc:
|
||||
if nSrc == 0 {
|
||||
src = grow(src, 0)
|
||||
}
|
||||
default:
|
||||
return string(dst[:pDst]), pSrc, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Bytes returns a new byte slice with the result of converting b[:n] using t,
|
||||
// where n <= len(b). If err == nil, n will be len(b).
|
||||
func Bytes(t Transformer, b []byte) (result []byte, n int, err error) {
|
||||
dst := make([]byte, len(b))
|
||||
pDst, pSrc := 0, 0
|
||||
for {
|
||||
nDst, nSrc, err := t.Transform(dst[pDst:], b[pSrc:], true)
|
||||
pDst += nDst
|
||||
pSrc += nSrc
|
||||
if err != ErrShortDst {
|
||||
return dst[:pDst], pSrc, err
|
||||
}
|
||||
|
||||
// Grow the destination buffer, but do not grow as long as we can make
|
||||
// progress. This may avoid excessive allocations.
|
||||
if nDst == 0 {
|
||||
dst = grow(dst, pDst)
|
||||
}
|
||||
out2 := make([]byte, sz)
|
||||
copy(out2, out[:n])
|
||||
out = out2
|
||||
}
|
||||
}
|
||||
|
||||
200
Godeps/_workspace/src/code.google.com/p/go.text/transform/transform_test.go
generated
vendored
200
Godeps/_workspace/src/code.google.com/p/go.text/transform/transform_test.go
generated
vendored
@@ -12,6 +12,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
@@ -132,6 +133,43 @@ func (e rleEncode) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err e
|
||||
return nDst, nSrc, nil
|
||||
}
|
||||
|
||||
// trickler consumes all input bytes, but writes a single byte at a time to dst.
|
||||
type trickler []byte
|
||||
|
||||
func (t *trickler) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
||||
*t = append(*t, src...)
|
||||
if len(*t) == 0 {
|
||||
return 0, 0, nil
|
||||
}
|
||||
if len(dst) == 0 {
|
||||
return 0, len(src), ErrShortDst
|
||||
}
|
||||
dst[0] = (*t)[0]
|
||||
*t = (*t)[1:]
|
||||
if len(*t) > 0 {
|
||||
err = ErrShortDst
|
||||
}
|
||||
return 1, len(src), err
|
||||
}
|
||||
|
||||
// delayedTrickler is like trickler, but delays writing output to dst. This is
|
||||
// highly unlikely to be relevant in practice, but it seems like a good idea
|
||||
// to have some tolerance as long as progress can be detected.
|
||||
type delayedTrickler []byte
|
||||
|
||||
func (t *delayedTrickler) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
||||
if len(*t) > 0 && len(dst) > 0 {
|
||||
dst[0] = (*t)[0]
|
||||
*t = (*t)[1:]
|
||||
nDst = 1
|
||||
}
|
||||
*t = append(*t, src...)
|
||||
if len(*t) > 0 {
|
||||
err = ErrShortDst
|
||||
}
|
||||
return nDst, len(src), err
|
||||
}
|
||||
|
||||
type testCase struct {
|
||||
desc string
|
||||
t Transformer
|
||||
@@ -170,6 +208,15 @@ func (c chain) String() string {
|
||||
}
|
||||
|
||||
var testCases = []testCase{
|
||||
{
|
||||
desc: "empty",
|
||||
t: lowerCaseASCII{},
|
||||
src: "",
|
||||
dstSize: 100,
|
||||
srcSize: 100,
|
||||
wantStr: "",
|
||||
},
|
||||
|
||||
{
|
||||
desc: "basic",
|
||||
t: lowerCaseASCII{},
|
||||
@@ -378,6 +425,24 @@ var testCases = []testCase{
|
||||
ioSize: 10,
|
||||
wantStr: "4a6b2b4c4d1d",
|
||||
},
|
||||
|
||||
{
|
||||
desc: "trickler",
|
||||
t: &trickler{},
|
||||
src: "abcdefghijklm",
|
||||
dstSize: 3,
|
||||
srcSize: 15,
|
||||
wantStr: "abcdefghijklm",
|
||||
},
|
||||
|
||||
{
|
||||
desc: "delayedTrickler",
|
||||
t: &delayedTrickler{},
|
||||
src: "abcdefghijklm",
|
||||
dstSize: 3,
|
||||
srcSize: 15,
|
||||
wantStr: "abcdefghijklm",
|
||||
},
|
||||
}
|
||||
|
||||
func TestReader(t *testing.T) {
|
||||
@@ -685,7 +750,7 @@ func doTransform(tc testCase) (res string, iter int, err error) {
|
||||
switch {
|
||||
case err == nil && len(in) != 0:
|
||||
case err == ErrShortSrc && nSrc > 0:
|
||||
case err == ErrShortDst && nDst > 0:
|
||||
case err == ErrShortDst && (nDst > 0 || nSrc > 0):
|
||||
default:
|
||||
return string(out), iter, err
|
||||
}
|
||||
@@ -875,27 +940,136 @@ func TestRemoveFunc(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestBytes(t *testing.T) {
|
||||
func testString(t *testing.T, f func(Transformer, string) (string, int, error)) {
|
||||
for _, tt := range append(testCases, chainTests()...) {
|
||||
if tt.desc == "allowStutter = true" {
|
||||
// We don't have control over the buffer size, so we eliminate tests
|
||||
// that depend on a specific buffer size being set.
|
||||
continue
|
||||
}
|
||||
got := Bytes(tt.t, []byte(tt.src))
|
||||
if tt.wantErr != nil {
|
||||
if tt.wantErr != ErrShortDst && tt.wantErr != ErrShortSrc {
|
||||
// Bytes should return nil for non-recoverable errors.
|
||||
if g, w := (got == nil), (tt.wantErr != nil); g != w {
|
||||
t.Errorf("%s:error: got %v; want %v", tt.desc, g, w)
|
||||
}
|
||||
}
|
||||
// The output strings in the tests that expect an error will
|
||||
// almost certainly not be the same as the result of Bytes.
|
||||
reset(tt.t)
|
||||
if tt.wantErr == ErrShortDst || tt.wantErr == ErrShortSrc {
|
||||
// The result string will be different.
|
||||
continue
|
||||
}
|
||||
if string(got) != tt.wantStr {
|
||||
got, n, err := f(tt.t, tt.src)
|
||||
if tt.wantErr != err {
|
||||
t.Errorf("%s:error: got %v; want %v", tt.desc, err, tt.wantErr)
|
||||
}
|
||||
if got, want := err == nil, n == len(tt.src); got != want {
|
||||
t.Errorf("%s:n: got %v; want %v", tt.desc, got, want)
|
||||
}
|
||||
if got != tt.wantStr {
|
||||
t.Errorf("%s:string: got %q; want %q", tt.desc, got, tt.wantStr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestBytes(t *testing.T) {
|
||||
testString(t, func(z Transformer, s string) (string, int, error) {
|
||||
b, n, err := Bytes(z, []byte(s))
|
||||
return string(b), n, err
|
||||
})
|
||||
}
|
||||
|
||||
func TestString(t *testing.T) {
|
||||
testString(t, String)
|
||||
|
||||
// Overrun the internal destination buffer.
|
||||
for i, s := range []string{
|
||||
strings.Repeat("a", initialBufSize-1),
|
||||
strings.Repeat("a", initialBufSize+0),
|
||||
strings.Repeat("a", initialBufSize+1),
|
||||
strings.Repeat("A", initialBufSize-1),
|
||||
strings.Repeat("A", initialBufSize+0),
|
||||
strings.Repeat("A", initialBufSize+1),
|
||||
strings.Repeat("A", 2*initialBufSize-1),
|
||||
strings.Repeat("A", 2*initialBufSize+0),
|
||||
strings.Repeat("A", 2*initialBufSize+1),
|
||||
strings.Repeat("a", initialBufSize-2) + "A",
|
||||
strings.Repeat("a", initialBufSize-1) + "A",
|
||||
strings.Repeat("a", initialBufSize+0) + "A",
|
||||
strings.Repeat("a", initialBufSize+1) + "A",
|
||||
} {
|
||||
got, _, _ := String(lowerCaseASCII{}, s)
|
||||
if want := strings.ToLower(s); got != want {
|
||||
t.Errorf("%d:dst buffer test: got %s (%d); want %s (%d)", i, got, len(got), want, len(want))
|
||||
}
|
||||
}
|
||||
|
||||
// Overrun the internal source buffer.
|
||||
for i, s := range []string{
|
||||
strings.Repeat("a", initialBufSize-1),
|
||||
strings.Repeat("a", initialBufSize+0),
|
||||
strings.Repeat("a", initialBufSize+1),
|
||||
strings.Repeat("a", 2*initialBufSize+1),
|
||||
strings.Repeat("a", 2*initialBufSize+0),
|
||||
strings.Repeat("a", 2*initialBufSize+1),
|
||||
} {
|
||||
got, _, _ := String(rleEncode{}, s)
|
||||
if want := fmt.Sprintf("%da", len(s)); got != want {
|
||||
t.Errorf("%d:src buffer test: got %s (%d); want %s (%d)", i, got, len(got), want, len(want))
|
||||
}
|
||||
}
|
||||
|
||||
// Test allocations for non-changing strings.
|
||||
// Note we still need to allocate a single buffer.
|
||||
for i, s := range []string{
|
||||
"",
|
||||
"123",
|
||||
"123456789",
|
||||
strings.Repeat("a", initialBufSize),
|
||||
strings.Repeat("a", 10*initialBufSize),
|
||||
} {
|
||||
if n := testing.AllocsPerRun(5, func() { String(&lowerCaseASCII{}, s) }); n > 1 {
|
||||
t.Errorf("%d: #allocs was %f; want 1", i, n)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestBytesAllocation tests that buffer growth stays limited with the trickler
|
||||
// transformer, which behaves oddly but within spec. In case buffer growth is
|
||||
// not correctly handled, the test will either panic with a failed allocation or
|
||||
// thrash. To ensure the tests terminate under the last condition, we time out
|
||||
// after some sufficiently long period of time.
|
||||
func TestBytesAllocation(t *testing.T) {
|
||||
done := make(chan bool)
|
||||
go func() {
|
||||
in := bytes.Repeat([]byte{'a'}, 1000)
|
||||
tr := trickler(make([]byte, 1))
|
||||
Bytes(&tr, in)
|
||||
done <- true
|
||||
}()
|
||||
select {
|
||||
case <-done:
|
||||
case <-time.After(3 * time.Second):
|
||||
t.Error("time out, likely due to excessive allocation")
|
||||
}
|
||||
}
|
||||
|
||||
// TestStringAllocation tests that buffer growth stays limited with the trickler
|
||||
// transformer, which behaves oddly but within spec. In case buffer growth is
|
||||
// not correctly handled, the test will either panic with a failed allocation or
|
||||
// thrash. To ensure the tests terminate under the last condition, we time out
|
||||
// after some sufficiently long period of time.
|
||||
func TestStringAllocation(t *testing.T) {
|
||||
done := make(chan bool)
|
||||
go func() {
|
||||
in := strings.Repeat("a", 1000)
|
||||
tr := trickler(make([]byte, 1))
|
||||
String(&tr, in)
|
||||
done <- true
|
||||
}()
|
||||
select {
|
||||
case <-done:
|
||||
case <-time.After(3 * time.Second):
|
||||
t.Error("time out, likely due to excessive allocation")
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkStringLower(b *testing.B) {
|
||||
in := strings.Repeat("a", 4096)
|
||||
for i := 0; i < b.N; i++ {
|
||||
String(&lowerCaseASCII{}, in)
|
||||
}
|
||||
}
|
||||
|
||||
212
Godeps/_workspace/src/code.google.com/p/go.text/unicode/norm/maketables.go
generated
vendored
212
Godeps/_workspace/src/code.google.com/p/go.text/unicode/norm/maketables.go
generated
vendored
@@ -11,7 +11,6 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"flag"
|
||||
"fmt"
|
||||
@@ -24,6 +23,8 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"code.google.com/p/go.text/internal/ucd"
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -63,31 +64,7 @@ var localFiles = flag.Bool("local",
|
||||
|
||||
var logger = log.New(os.Stderr, "", log.Lshortfile)
|
||||
|
||||
// UnicodeData.txt has form:
|
||||
// 0037;DIGIT SEVEN;Nd;0;EN;;7;7;7;N;;;;;
|
||||
// 007A;LATIN SMALL LETTER Z;Ll;0;L;;;;;N;;;005A;;005A
|
||||
// See http://unicode.org/reports/tr44/ for full explanation
|
||||
// The fields:
|
||||
const (
|
||||
FCodePoint = iota
|
||||
FName
|
||||
FGeneralCategory
|
||||
FCanonicalCombiningClass
|
||||
FBidiClass
|
||||
FDecompMapping
|
||||
FDecimalValue
|
||||
FDigitValue
|
||||
FNumericValue
|
||||
FBidiMirrored
|
||||
FUnicode1Name
|
||||
FISOComment
|
||||
FSimpleUppercaseMapping
|
||||
FSimpleLowercaseMapping
|
||||
FSimpleTitlecaseMapping
|
||||
NumField
|
||||
|
||||
MaxChar = 0x10FFFF // anything above this shouldn't exist
|
||||
)
|
||||
const MaxChar = 0x10FFFF // anything above this shouldn't exist
|
||||
|
||||
// Quick Check properties of runes allow us to quickly
|
||||
// determine whether a rune may occur in a normal form.
|
||||
@@ -232,7 +209,7 @@ func openReader(file string) (input io.ReadCloser) {
|
||||
return
|
||||
}
|
||||
|
||||
func parseDecomposition(s string, skipfirst bool) (a []rune, e error) {
|
||||
func parseDecomposition(s string, skipfirst bool) (a []rune, err error) {
|
||||
decomp := strings.Split(s, " ")
|
||||
if len(decomp) > 0 && skipfirst {
|
||||
decomp = decomp[1:]
|
||||
@@ -247,56 +224,31 @@ func parseDecomposition(s string, skipfirst bool) (a []rune, e error) {
|
||||
return a, nil
|
||||
}
|
||||
|
||||
func parseCharacter(line string) {
|
||||
field := strings.Split(line, ";")
|
||||
if len(field) != NumField {
|
||||
logger.Fatalf("%5s: %d fields (expected %d)\n", line, len(field), NumField)
|
||||
}
|
||||
x, err := strconv.ParseUint(field[FCodePoint], 16, 64)
|
||||
point := int(x)
|
||||
if err != nil {
|
||||
logger.Fatalf("%.5s...: %s", line, err)
|
||||
}
|
||||
if point == 0 {
|
||||
return // not interesting and we use 0 as unset
|
||||
}
|
||||
if point > MaxChar {
|
||||
logger.Fatalf("%5s: Rune %X > MaxChar (%X)", line, point, MaxChar)
|
||||
return
|
||||
}
|
||||
state := SNormal
|
||||
switch {
|
||||
case strings.Index(field[FName], ", First>") > 0:
|
||||
state = SFirst
|
||||
case strings.Index(field[FName], ", Last>") > 0:
|
||||
state = SLast
|
||||
}
|
||||
firstChar := lastChar + 1
|
||||
lastChar = rune(point)
|
||||
if state != SLast {
|
||||
firstChar = lastChar
|
||||
}
|
||||
x, err = strconv.ParseUint(field[FCanonicalCombiningClass], 10, 64)
|
||||
if err != nil {
|
||||
logger.Fatalf("%U: bad ccc field: %s", int(x), err)
|
||||
}
|
||||
ccc := uint8(x)
|
||||
decmap := field[FDecompMapping]
|
||||
exp, e := parseDecomposition(decmap, false)
|
||||
isCompat := false
|
||||
if e != nil {
|
||||
if len(decmap) > 0 {
|
||||
exp, e = parseDecomposition(decmap, true)
|
||||
if e != nil {
|
||||
logger.Fatalf(`%U: bad decomp |%v|: "%s"`, int(x), decmap, e)
|
||||
func loadUnicodeData() {
|
||||
f := openReader("UnicodeData.txt")
|
||||
defer f.Close()
|
||||
p := ucd.New(f)
|
||||
for p.Next() {
|
||||
r := p.Rune(ucd.CodePoint)
|
||||
char := &chars[r]
|
||||
|
||||
char.ccc = uint8(p.Uint(ucd.CanonicalCombiningClass))
|
||||
decmap := p.String(ucd.DecompMapping)
|
||||
|
||||
exp, err := parseDecomposition(decmap, false)
|
||||
isCompat := false
|
||||
if err != nil {
|
||||
if len(decmap) > 0 {
|
||||
exp, err = parseDecomposition(decmap, true)
|
||||
if err != nil {
|
||||
logger.Fatalf(`%U: bad decomp |%v|: "%s"`, r, decmap, err)
|
||||
}
|
||||
isCompat = true
|
||||
}
|
||||
isCompat = true
|
||||
}
|
||||
}
|
||||
for i := firstChar; i <= lastChar; i++ {
|
||||
char := &chars[i]
|
||||
char.name = field[FName]
|
||||
char.codePoint = i
|
||||
|
||||
char.name = p.String(ucd.Name)
|
||||
char.codePoint = r
|
||||
char.forms[FCompatibility].decomp = exp
|
||||
if !isCompat {
|
||||
char.forms[FCanonical].decomp = exp
|
||||
@@ -306,24 +258,9 @@ func parseCharacter(line string) {
|
||||
if len(decmap) > 0 {
|
||||
char.forms[FCompatibility].decomp = exp
|
||||
}
|
||||
char.ccc = ccc
|
||||
char.state = SMissing
|
||||
if i == lastChar {
|
||||
char.state = state
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func loadUnicodeData() {
|
||||
f := openReader("UnicodeData.txt")
|
||||
defer f.Close()
|
||||
scanner := bufio.NewScanner(f)
|
||||
for scanner.Scan() {
|
||||
parseCharacter(scanner.Text())
|
||||
}
|
||||
if scanner.Err() != nil {
|
||||
logger.Fatal(scanner.Err())
|
||||
if err := p.Err(); err != nil {
|
||||
logger.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -354,47 +291,22 @@ func compactCCC() {
|
||||
}
|
||||
}
|
||||
|
||||
var singlePointRe = regexp.MustCompile(`^([0-9A-F]+) *$`)
|
||||
|
||||
// CompositionExclusions.txt has form:
|
||||
// 0958 # ...
|
||||
// See http://unicode.org/reports/tr44/ for full explanation
|
||||
func parseExclusion(line string) int {
|
||||
comment := strings.Index(line, "#")
|
||||
if comment >= 0 {
|
||||
line = line[0:comment]
|
||||
}
|
||||
if len(line) == 0 {
|
||||
return 0
|
||||
}
|
||||
matches := singlePointRe.FindStringSubmatch(line)
|
||||
if len(matches) != 2 {
|
||||
logger.Fatalf("%s: %d matches (expected 1)\n", line, len(matches))
|
||||
}
|
||||
point, err := strconv.ParseUint(matches[1], 16, 64)
|
||||
if err != nil {
|
||||
logger.Fatalf("%.5s...: %s", line, err)
|
||||
}
|
||||
return int(point)
|
||||
}
|
||||
|
||||
func loadCompositionExclusions() {
|
||||
f := openReader("CompositionExclusions.txt")
|
||||
defer f.Close()
|
||||
scanner := bufio.NewScanner(f)
|
||||
for scanner.Scan() {
|
||||
point := parseExclusion(scanner.Text())
|
||||
if point == 0 {
|
||||
continue
|
||||
}
|
||||
c := &chars[point]
|
||||
p := ucd.New(f)
|
||||
for p.Next() {
|
||||
c := &chars[p.Rune(0)]
|
||||
if c.excludeInComp {
|
||||
logger.Fatalf("%U: Duplicate entry in exclusions.", c.codePoint)
|
||||
}
|
||||
c.excludeInComp = true
|
||||
}
|
||||
if scanner.Err() != nil {
|
||||
log.Fatal(scanner.Err())
|
||||
if e := p.Err(); e != nil {
|
||||
logger.Fatal(e)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -988,8 +900,6 @@ func verifyComputed() {
|
||||
}
|
||||
}
|
||||
|
||||
var qcRe = regexp.MustCompile(`([0-9A-F\.]+) *; (NF.*_QC); ([YNM]) #.*`)
|
||||
|
||||
// Use values in DerivedNormalizationProps.txt to compare against the
|
||||
// values we computed.
|
||||
// DerivedNormalizationProps.txt has form:
|
||||
@@ -999,27 +909,13 @@ var qcRe = regexp.MustCompile(`([0-9A-F\.]+) *; (NF.*_QC); ([YNM]) #.*`)
|
||||
func testDerived() {
|
||||
f := openReader("DerivedNormalizationProps.txt")
|
||||
defer f.Close()
|
||||
scanner := bufio.NewScanner(f)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
qc := qcRe.FindStringSubmatch(line)
|
||||
if qc == nil {
|
||||
continue
|
||||
}
|
||||
rng := strings.Split(qc[1], "..")
|
||||
i, err := strconv.ParseUint(rng[0], 16, 64)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
j := i
|
||||
if len(rng) > 1 {
|
||||
j, err = strconv.ParseUint(rng[1], 16, 64)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
p := ucd.New(f)
|
||||
for p.Next() {
|
||||
r := p.Rune(0)
|
||||
c := &chars[r]
|
||||
|
||||
var ftype, mode int
|
||||
qt := strings.TrimSpace(qc[2])
|
||||
qt := p.String(1)
|
||||
switch qt {
|
||||
case "NFC_QC":
|
||||
ftype, mode = FCanonical, MComposed
|
||||
@@ -1030,10 +926,10 @@ func testDerived() {
|
||||
case "NFKD_QC":
|
||||
ftype, mode = FCompatibility, MDecomposed
|
||||
default:
|
||||
log.Fatalf(`Unexpected quick check type "%s"`, qt)
|
||||
continue
|
||||
}
|
||||
var qr QCResult
|
||||
switch qc[3] {
|
||||
switch p.String(2) {
|
||||
case "Y":
|
||||
qr = QCYes
|
||||
case "N":
|
||||
@@ -1041,27 +937,15 @@ func testDerived() {
|
||||
case "M":
|
||||
qr = QCMaybe
|
||||
default:
|
||||
log.Fatalf(`Unexpected quick check value "%s"`, qc[3])
|
||||
log.Fatalf(`Unexpected quick check value "%s"`, p.String(2))
|
||||
}
|
||||
var lastFailed bool
|
||||
// Verify current
|
||||
for ; i <= j; i++ {
|
||||
c := &chars[int(i)]
|
||||
c.forms[ftype].verified[mode] = true
|
||||
curqr := c.forms[ftype].quickCheck[mode]
|
||||
if curqr != qr {
|
||||
if !lastFailed {
|
||||
logger.Printf("%s: %.4X..%.4X -- %s\n",
|
||||
qt, int(i), int(j), line[0:50])
|
||||
}
|
||||
logger.Printf("%U: FAILED %s (was %v need %v)\n",
|
||||
int(i), qt, curqr, qr)
|
||||
lastFailed = true
|
||||
}
|
||||
if got := c.forms[ftype].quickCheck[mode]; got != qr {
|
||||
logger.Printf("%U: FAILED %s (was %v need %v)\n", r, qt, got, qr)
|
||||
}
|
||||
c.forms[ftype].verified[mode] = true
|
||||
}
|
||||
if scanner.Err() != nil {
|
||||
logger.Fatal(scanner.Err())
|
||||
if err := p.Err(); err != nil {
|
||||
logger.Fatal(err)
|
||||
}
|
||||
// Any unspecified value must be QCYes. Verify this.
|
||||
for i, c := range chars {
|
||||
|
||||
124
Godeps/_workspace/src/code.google.com/p/snappy-go/snappy/decode.go
generated
vendored
Normal file
124
Godeps/_workspace/src/code.google.com/p/snappy-go/snappy/decode.go
generated
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
// Copyright 2011 The Snappy-Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package snappy
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
)
|
||||
|
||||
// ErrCorrupt reports that the input is invalid.
|
||||
var ErrCorrupt = errors.New("snappy: corrupt input")
|
||||
|
||||
// DecodedLen returns the length of the decoded block.
|
||||
func DecodedLen(src []byte) (int, error) {
|
||||
v, _, err := decodedLen(src)
|
||||
return v, err
|
||||
}
|
||||
|
||||
// decodedLen returns the length of the decoded block and the number of bytes
|
||||
// that the length header occupied.
|
||||
func decodedLen(src []byte) (blockLen, headerLen int, err error) {
|
||||
v, n := binary.Uvarint(src)
|
||||
if n == 0 {
|
||||
return 0, 0, ErrCorrupt
|
||||
}
|
||||
if uint64(int(v)) != v {
|
||||
return 0, 0, errors.New("snappy: decoded block is too large")
|
||||
}
|
||||
return int(v), n, nil
|
||||
}
|
||||
|
||||
// Decode returns the decoded form of src. The returned slice may be a sub-
|
||||
// slice of dst if dst was large enough to hold the entire decoded block.
|
||||
// Otherwise, a newly allocated slice will be returned.
|
||||
// It is valid to pass a nil dst.
|
||||
func Decode(dst, src []byte) ([]byte, error) {
|
||||
dLen, s, err := decodedLen(src)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(dst) < dLen {
|
||||
dst = make([]byte, dLen)
|
||||
}
|
||||
|
||||
var d, offset, length int
|
||||
for s < len(src) {
|
||||
switch src[s] & 0x03 {
|
||||
case tagLiteral:
|
||||
x := uint(src[s] >> 2)
|
||||
switch {
|
||||
case x < 60:
|
||||
s += 1
|
||||
case x == 60:
|
||||
s += 2
|
||||
if s > len(src) {
|
||||
return nil, ErrCorrupt
|
||||
}
|
||||
x = uint(src[s-1])
|
||||
case x == 61:
|
||||
s += 3
|
||||
if s > len(src) {
|
||||
return nil, ErrCorrupt
|
||||
}
|
||||
x = uint(src[s-2]) | uint(src[s-1])<<8
|
||||
case x == 62:
|
||||
s += 4
|
||||
if s > len(src) {
|
||||
return nil, ErrCorrupt
|
||||
}
|
||||
x = uint(src[s-3]) | uint(src[s-2])<<8 | uint(src[s-1])<<16
|
||||
case x == 63:
|
||||
s += 5
|
||||
if s > len(src) {
|
||||
return nil, ErrCorrupt
|
||||
}
|
||||
x = uint(src[s-4]) | uint(src[s-3])<<8 | uint(src[s-2])<<16 | uint(src[s-1])<<24
|
||||
}
|
||||
length = int(x + 1)
|
||||
if length <= 0 {
|
||||
return nil, errors.New("snappy: unsupported literal length")
|
||||
}
|
||||
if length > len(dst)-d || length > len(src)-s {
|
||||
return nil, ErrCorrupt
|
||||
}
|
||||
copy(dst[d:], src[s:s+length])
|
||||
d += length
|
||||
s += length
|
||||
continue
|
||||
|
||||
case tagCopy1:
|
||||
s += 2
|
||||
if s > len(src) {
|
||||
return nil, ErrCorrupt
|
||||
}
|
||||
length = 4 + int(src[s-2])>>2&0x7
|
||||
offset = int(src[s-2])&0xe0<<3 | int(src[s-1])
|
||||
|
||||
case tagCopy2:
|
||||
s += 3
|
||||
if s > len(src) {
|
||||
return nil, ErrCorrupt
|
||||
}
|
||||
length = 1 + int(src[s-3])>>2
|
||||
offset = int(src[s-2]) | int(src[s-1])<<8
|
||||
|
||||
case tagCopy4:
|
||||
return nil, errors.New("snappy: unsupported COPY_4 tag")
|
||||
}
|
||||
|
||||
end := d + length
|
||||
if offset > d || end > len(dst) {
|
||||
return nil, ErrCorrupt
|
||||
}
|
||||
for ; d < end; d++ {
|
||||
dst[d] = dst[d-offset]
|
||||
}
|
||||
}
|
||||
if d != dLen {
|
||||
return nil, ErrCorrupt
|
||||
}
|
||||
return dst[:d], nil
|
||||
}
|
||||
174
Godeps/_workspace/src/code.google.com/p/snappy-go/snappy/encode.go
generated
vendored
Normal file
174
Godeps/_workspace/src/code.google.com/p/snappy-go/snappy/encode.go
generated
vendored
Normal file
@@ -0,0 +1,174 @@
|
||||
// Copyright 2011 The Snappy-Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package snappy
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
)
|
||||
|
||||
// We limit how far copy back-references can go, the same as the C++ code.
|
||||
const maxOffset = 1 << 15
|
||||
|
||||
// emitLiteral writes a literal chunk and returns the number of bytes written.
|
||||
func emitLiteral(dst, lit []byte) int {
|
||||
i, n := 0, uint(len(lit)-1)
|
||||
switch {
|
||||
case n < 60:
|
||||
dst[0] = uint8(n)<<2 | tagLiteral
|
||||
i = 1
|
||||
case n < 1<<8:
|
||||
dst[0] = 60<<2 | tagLiteral
|
||||
dst[1] = uint8(n)
|
||||
i = 2
|
||||
case n < 1<<16:
|
||||
dst[0] = 61<<2 | tagLiteral
|
||||
dst[1] = uint8(n)
|
||||
dst[2] = uint8(n >> 8)
|
||||
i = 3
|
||||
case n < 1<<24:
|
||||
dst[0] = 62<<2 | tagLiteral
|
||||
dst[1] = uint8(n)
|
||||
dst[2] = uint8(n >> 8)
|
||||
dst[3] = uint8(n >> 16)
|
||||
i = 4
|
||||
case int64(n) < 1<<32:
|
||||
dst[0] = 63<<2 | tagLiteral
|
||||
dst[1] = uint8(n)
|
||||
dst[2] = uint8(n >> 8)
|
||||
dst[3] = uint8(n >> 16)
|
||||
dst[4] = uint8(n >> 24)
|
||||
i = 5
|
||||
default:
|
||||
panic("snappy: source buffer is too long")
|
||||
}
|
||||
if copy(dst[i:], lit) != len(lit) {
|
||||
panic("snappy: destination buffer is too short")
|
||||
}
|
||||
return i + len(lit)
|
||||
}
|
||||
|
||||
// emitCopy writes a copy chunk and returns the number of bytes written.
|
||||
func emitCopy(dst []byte, offset, length int) int {
|
||||
i := 0
|
||||
for length > 0 {
|
||||
x := length - 4
|
||||
if 0 <= x && x < 1<<3 && offset < 1<<11 {
|
||||
dst[i+0] = uint8(offset>>8)&0x07<<5 | uint8(x)<<2 | tagCopy1
|
||||
dst[i+1] = uint8(offset)
|
||||
i += 2
|
||||
break
|
||||
}
|
||||
|
||||
x = length
|
||||
if x > 1<<6 {
|
||||
x = 1 << 6
|
||||
}
|
||||
dst[i+0] = uint8(x-1)<<2 | tagCopy2
|
||||
dst[i+1] = uint8(offset)
|
||||
dst[i+2] = uint8(offset >> 8)
|
||||
i += 3
|
||||
length -= x
|
||||
}
|
||||
return i
|
||||
}
|
||||
|
||||
// Encode returns the encoded form of src. The returned slice may be a sub-
|
||||
// slice of dst if dst was large enough to hold the entire encoded block.
|
||||
// Otherwise, a newly allocated slice will be returned.
|
||||
// It is valid to pass a nil dst.
|
||||
func Encode(dst, src []byte) ([]byte, error) {
|
||||
if n := MaxEncodedLen(len(src)); len(dst) < n {
|
||||
dst = make([]byte, n)
|
||||
}
|
||||
|
||||
// The block starts with the varint-encoded length of the decompressed bytes.
|
||||
d := binary.PutUvarint(dst, uint64(len(src)))
|
||||
|
||||
// Return early if src is short.
|
||||
if len(src) <= 4 {
|
||||
if len(src) != 0 {
|
||||
d += emitLiteral(dst[d:], src)
|
||||
}
|
||||
return dst[:d], nil
|
||||
}
|
||||
|
||||
// Initialize the hash table. Its size ranges from 1<<8 to 1<<14 inclusive.
|
||||
const maxTableSize = 1 << 14
|
||||
shift, tableSize := uint(32-8), 1<<8
|
||||
for tableSize < maxTableSize && tableSize < len(src) {
|
||||
shift--
|
||||
tableSize *= 2
|
||||
}
|
||||
var table [maxTableSize]int
|
||||
|
||||
// Iterate over the source bytes.
|
||||
var (
|
||||
s int // The iterator position.
|
||||
t int // The last position with the same hash as s.
|
||||
lit int // The start position of any pending literal bytes.
|
||||
)
|
||||
for s+3 < len(src) {
|
||||
// Update the hash table.
|
||||
b0, b1, b2, b3 := src[s], src[s+1], src[s+2], src[s+3]
|
||||
h := uint32(b0) | uint32(b1)<<8 | uint32(b2)<<16 | uint32(b3)<<24
|
||||
p := &table[(h*0x1e35a7bd)>>shift]
|
||||
// We need to to store values in [-1, inf) in table. To save
|
||||
// some initialization time, (re)use the table's zero value
|
||||
// and shift the values against this zero: add 1 on writes,
|
||||
// subtract 1 on reads.
|
||||
t, *p = *p-1, s+1
|
||||
// If t is invalid or src[s:s+4] differs from src[t:t+4], accumulate a literal byte.
|
||||
if t < 0 || s-t >= maxOffset || b0 != src[t] || b1 != src[t+1] || b2 != src[t+2] || b3 != src[t+3] {
|
||||
s++
|
||||
continue
|
||||
}
|
||||
// Otherwise, we have a match. First, emit any pending literal bytes.
|
||||
if lit != s {
|
||||
d += emitLiteral(dst[d:], src[lit:s])
|
||||
}
|
||||
// Extend the match to be as long as possible.
|
||||
s0 := s
|
||||
s, t = s+4, t+4
|
||||
for s < len(src) && src[s] == src[t] {
|
||||
s++
|
||||
t++
|
||||
}
|
||||
// Emit the copied bytes.
|
||||
d += emitCopy(dst[d:], s-t, s-s0)
|
||||
lit = s
|
||||
}
|
||||
|
||||
// Emit any final pending literal bytes and return.
|
||||
if lit != len(src) {
|
||||
d += emitLiteral(dst[d:], src[lit:])
|
||||
}
|
||||
return dst[:d], nil
|
||||
}
|
||||
|
||||
// MaxEncodedLen returns the maximum length of a snappy block, given its
|
||||
// uncompressed length.
|
||||
func MaxEncodedLen(srcLen int) int {
|
||||
// Compressed data can be defined as:
|
||||
// compressed := item* literal*
|
||||
// item := literal* copy
|
||||
//
|
||||
// The trailing literal sequence has a space blowup of at most 62/60
|
||||
// since a literal of length 60 needs one tag byte + one extra byte
|
||||
// for length information.
|
||||
//
|
||||
// Item blowup is trickier to measure. Suppose the "copy" op copies
|
||||
// 4 bytes of data. Because of a special check in the encoding code,
|
||||
// we produce a 4-byte copy only if the offset is < 65536. Therefore
|
||||
// the copy op takes 3 bytes to encode, and this type of item leads
|
||||
// to at most the 62/60 blowup for representing literals.
|
||||
//
|
||||
// Suppose the "copy" op copies 5 bytes of data. If the offset is big
|
||||
// enough, it will take 5 bytes to encode the copy op. Therefore the
|
||||
// worst case here is a one-byte literal followed by a five-byte copy.
|
||||
// That is, 6 bytes of input turn into 7 bytes of "compressed" data.
|
||||
//
|
||||
// This last factor dominates the blowup, so the final estimate is:
|
||||
return 32 + srcLen + srcLen/6
|
||||
}
|
||||
38
Godeps/_workspace/src/code.google.com/p/snappy-go/snappy/snappy.go
generated
vendored
Normal file
38
Godeps/_workspace/src/code.google.com/p/snappy-go/snappy/snappy.go
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
// Copyright 2011 The Snappy-Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package snappy implements the snappy block-based compression format.
|
||||
// It aims for very high speeds and reasonable compression.
|
||||
//
|
||||
// The C++ snappy implementation is at http://code.google.com/p/snappy/
|
||||
package snappy
|
||||
|
||||
/*
|
||||
Each encoded block begins with the varint-encoded length of the decoded data,
|
||||
followed by a sequence of chunks. Chunks begin and end on byte boundaries. The
|
||||
first byte of each chunk is broken into its 2 least and 6 most significant bits
|
||||
called l and m: l ranges in [0, 4) and m ranges in [0, 64). l is the chunk tag.
|
||||
Zero means a literal tag. All other values mean a copy tag.
|
||||
|
||||
For literal tags:
|
||||
- If m < 60, the next 1 + m bytes are literal bytes.
|
||||
- Otherwise, let n be the little-endian unsigned integer denoted by the next
|
||||
m - 59 bytes. The next 1 + n bytes after that are literal bytes.
|
||||
|
||||
For copy tags, length bytes are copied from offset bytes ago, in the style of
|
||||
Lempel-Ziv compression algorithms. In particular:
|
||||
- For l == 1, the offset ranges in [0, 1<<11) and the length in [4, 12).
|
||||
The length is 4 + the low 3 bits of m. The high 3 bits of m form bits 8-10
|
||||
of the offset. The next byte is bits 0-7 of the offset.
|
||||
- For l == 2, the offset ranges in [0, 1<<16) and the length in [1, 65).
|
||||
The length is 1 + m. The offset is the little-endian unsigned integer
|
||||
denoted by the next 2 bytes.
|
||||
- For l == 3, this tag is a legacy format that is no longer supported.
|
||||
*/
|
||||
const (
|
||||
tagLiteral = 0x00
|
||||
tagCopy1 = 0x01
|
||||
tagCopy2 = 0x02
|
||||
tagCopy4 = 0x03
|
||||
)
|
||||
261
Godeps/_workspace/src/code.google.com/p/snappy-go/snappy/snappy_test.go
generated
vendored
Normal file
261
Godeps/_workspace/src/code.google.com/p/snappy-go/snappy/snappy_test.go
generated
vendored
Normal file
@@ -0,0 +1,261 @@
|
||||
// Copyright 2011 The Snappy-Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package snappy
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var download = flag.Bool("download", false, "If true, download any missing files before running benchmarks")
|
||||
|
||||
func roundtrip(b, ebuf, dbuf []byte) error {
|
||||
e, err := Encode(ebuf, b)
|
||||
if err != nil {
|
||||
return fmt.Errorf("encoding error: %v", err)
|
||||
}
|
||||
d, err := Decode(dbuf, e)
|
||||
if err != nil {
|
||||
return fmt.Errorf("decoding error: %v", err)
|
||||
}
|
||||
if !bytes.Equal(b, d) {
|
||||
return fmt.Errorf("roundtrip mismatch:\n\twant %v\n\tgot %v", b, d)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestEmpty(t *testing.T) {
|
||||
if err := roundtrip(nil, nil, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSmallCopy(t *testing.T) {
|
||||
for _, ebuf := range [][]byte{nil, make([]byte, 20), make([]byte, 64)} {
|
||||
for _, dbuf := range [][]byte{nil, make([]byte, 20), make([]byte, 64)} {
|
||||
for i := 0; i < 32; i++ {
|
||||
s := "aaaa" + strings.Repeat("b", i) + "aaaabbbb"
|
||||
if err := roundtrip([]byte(s), ebuf, dbuf); err != nil {
|
||||
t.Errorf("len(ebuf)=%d, len(dbuf)=%d, i=%d: %v", len(ebuf), len(dbuf), i, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSmallRand(t *testing.T) {
|
||||
rand.Seed(27354294)
|
||||
for n := 1; n < 20000; n += 23 {
|
||||
b := make([]byte, n)
|
||||
for i, _ := range b {
|
||||
b[i] = uint8(rand.Uint32())
|
||||
}
|
||||
if err := roundtrip(b, nil, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSmallRegular(t *testing.T) {
|
||||
for n := 1; n < 20000; n += 23 {
|
||||
b := make([]byte, n)
|
||||
for i, _ := range b {
|
||||
b[i] = uint8(i%10 + 'a')
|
||||
}
|
||||
if err := roundtrip(b, nil, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func benchDecode(b *testing.B, src []byte) {
|
||||
encoded, err := Encode(nil, src)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
// Bandwidth is in amount of uncompressed data.
|
||||
b.SetBytes(int64(len(src)))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
Decode(src, encoded)
|
||||
}
|
||||
}
|
||||
|
||||
func benchEncode(b *testing.B, src []byte) {
|
||||
// Bandwidth is in amount of uncompressed data.
|
||||
b.SetBytes(int64(len(src)))
|
||||
dst := make([]byte, MaxEncodedLen(len(src)))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
Encode(dst, src)
|
||||
}
|
||||
}
|
||||
|
||||
func readFile(b *testing.B, filename string) []byte {
|
||||
src, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
b.Fatalf("failed reading %s: %s", filename, err)
|
||||
}
|
||||
if len(src) == 0 {
|
||||
b.Fatalf("%s has zero length", filename)
|
||||
}
|
||||
return src
|
||||
}
|
||||
|
||||
// expand returns a slice of length n containing repeated copies of src.
|
||||
func expand(src []byte, n int) []byte {
|
||||
dst := make([]byte, n)
|
||||
for x := dst; len(x) > 0; {
|
||||
i := copy(x, src)
|
||||
x = x[i:]
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
func benchWords(b *testing.B, n int, decode bool) {
|
||||
// Note: the file is OS-language dependent so the resulting values are not
|
||||
// directly comparable for non-US-English OS installations.
|
||||
data := expand(readFile(b, "/usr/share/dict/words"), n)
|
||||
if decode {
|
||||
benchDecode(b, data)
|
||||
} else {
|
||||
benchEncode(b, data)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkWordsDecode1e3(b *testing.B) { benchWords(b, 1e3, true) }
|
||||
func BenchmarkWordsDecode1e4(b *testing.B) { benchWords(b, 1e4, true) }
|
||||
func BenchmarkWordsDecode1e5(b *testing.B) { benchWords(b, 1e5, true) }
|
||||
func BenchmarkWordsDecode1e6(b *testing.B) { benchWords(b, 1e6, true) }
|
||||
func BenchmarkWordsEncode1e3(b *testing.B) { benchWords(b, 1e3, false) }
|
||||
func BenchmarkWordsEncode1e4(b *testing.B) { benchWords(b, 1e4, false) }
|
||||
func BenchmarkWordsEncode1e5(b *testing.B) { benchWords(b, 1e5, false) }
|
||||
func BenchmarkWordsEncode1e6(b *testing.B) { benchWords(b, 1e6, false) }
|
||||
|
||||
// testFiles' values are copied directly from
|
||||
// https://code.google.com/p/snappy/source/browse/trunk/snappy_unittest.cc.
|
||||
// The label field is unused in snappy-go.
|
||||
var testFiles = []struct {
|
||||
label string
|
||||
filename string
|
||||
}{
|
||||
{"html", "html"},
|
||||
{"urls", "urls.10K"},
|
||||
{"jpg", "house.jpg"},
|
||||
{"pdf", "mapreduce-osdi-1.pdf"},
|
||||
{"html4", "html_x_4"},
|
||||
{"cp", "cp.html"},
|
||||
{"c", "fields.c"},
|
||||
{"lsp", "grammar.lsp"},
|
||||
{"xls", "kennedy.xls"},
|
||||
{"txt1", "alice29.txt"},
|
||||
{"txt2", "asyoulik.txt"},
|
||||
{"txt3", "lcet10.txt"},
|
||||
{"txt4", "plrabn12.txt"},
|
||||
{"bin", "ptt5"},
|
||||
{"sum", "sum"},
|
||||
{"man", "xargs.1"},
|
||||
{"pb", "geo.protodata"},
|
||||
{"gaviota", "kppkn.gtb"},
|
||||
}
|
||||
|
||||
// The test data files are present at this canonical URL.
|
||||
const baseURL = "https://snappy.googlecode.com/svn/trunk/testdata/"
|
||||
|
||||
func downloadTestdata(basename string) (errRet error) {
|
||||
filename := filepath.Join("testdata", basename)
|
||||
f, err := os.Create(filename)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create %s: %s", filename, err)
|
||||
}
|
||||
defer f.Close()
|
||||
defer func() {
|
||||
if errRet != nil {
|
||||
os.Remove(filename)
|
||||
}
|
||||
}()
|
||||
resp, err := http.Get(baseURL + basename)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to download %s: %s", baseURL+basename, err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
_, err = io.Copy(f, resp.Body)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to write %s: %s", filename, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func benchFile(b *testing.B, n int, decode bool) {
|
||||
filename := filepath.Join("testdata", testFiles[n].filename)
|
||||
if stat, err := os.Stat(filename); err != nil || stat.Size() == 0 {
|
||||
if !*download {
|
||||
b.Fatal("test data not found; skipping benchmark without the -download flag")
|
||||
}
|
||||
// Download the official snappy C++ implementation reference test data
|
||||
// files for benchmarking.
|
||||
if err := os.Mkdir("testdata", 0777); err != nil && !os.IsExist(err) {
|
||||
b.Fatalf("failed to create testdata: %s", err)
|
||||
}
|
||||
for _, tf := range testFiles {
|
||||
if err := downloadTestdata(tf.filename); err != nil {
|
||||
b.Fatalf("failed to download testdata: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
data := readFile(b, filename)
|
||||
if decode {
|
||||
benchDecode(b, data)
|
||||
} else {
|
||||
benchEncode(b, data)
|
||||
}
|
||||
}
|
||||
|
||||
// Naming convention is kept similar to what snappy's C++ implementation uses.
|
||||
func Benchmark_UFlat0(b *testing.B) { benchFile(b, 0, true) }
|
||||
func Benchmark_UFlat1(b *testing.B) { benchFile(b, 1, true) }
|
||||
func Benchmark_UFlat2(b *testing.B) { benchFile(b, 2, true) }
|
||||
func Benchmark_UFlat3(b *testing.B) { benchFile(b, 3, true) }
|
||||
func Benchmark_UFlat4(b *testing.B) { benchFile(b, 4, true) }
|
||||
func Benchmark_UFlat5(b *testing.B) { benchFile(b, 5, true) }
|
||||
func Benchmark_UFlat6(b *testing.B) { benchFile(b, 6, true) }
|
||||
func Benchmark_UFlat7(b *testing.B) { benchFile(b, 7, true) }
|
||||
func Benchmark_UFlat8(b *testing.B) { benchFile(b, 8, true) }
|
||||
func Benchmark_UFlat9(b *testing.B) { benchFile(b, 9, true) }
|
||||
func Benchmark_UFlat10(b *testing.B) { benchFile(b, 10, true) }
|
||||
func Benchmark_UFlat11(b *testing.B) { benchFile(b, 11, true) }
|
||||
func Benchmark_UFlat12(b *testing.B) { benchFile(b, 12, true) }
|
||||
func Benchmark_UFlat13(b *testing.B) { benchFile(b, 13, true) }
|
||||
func Benchmark_UFlat14(b *testing.B) { benchFile(b, 14, true) }
|
||||
func Benchmark_UFlat15(b *testing.B) { benchFile(b, 15, true) }
|
||||
func Benchmark_UFlat16(b *testing.B) { benchFile(b, 16, true) }
|
||||
func Benchmark_UFlat17(b *testing.B) { benchFile(b, 17, true) }
|
||||
func Benchmark_ZFlat0(b *testing.B) { benchFile(b, 0, false) }
|
||||
func Benchmark_ZFlat1(b *testing.B) { benchFile(b, 1, false) }
|
||||
func Benchmark_ZFlat2(b *testing.B) { benchFile(b, 2, false) }
|
||||
func Benchmark_ZFlat3(b *testing.B) { benchFile(b, 3, false) }
|
||||
func Benchmark_ZFlat4(b *testing.B) { benchFile(b, 4, false) }
|
||||
func Benchmark_ZFlat5(b *testing.B) { benchFile(b, 5, false) }
|
||||
func Benchmark_ZFlat6(b *testing.B) { benchFile(b, 6, false) }
|
||||
func Benchmark_ZFlat7(b *testing.B) { benchFile(b, 7, false) }
|
||||
func Benchmark_ZFlat8(b *testing.B) { benchFile(b, 8, false) }
|
||||
func Benchmark_ZFlat9(b *testing.B) { benchFile(b, 9, false) }
|
||||
func Benchmark_ZFlat10(b *testing.B) { benchFile(b, 10, false) }
|
||||
func Benchmark_ZFlat11(b *testing.B) { benchFile(b, 11, false) }
|
||||
func Benchmark_ZFlat12(b *testing.B) { benchFile(b, 12, false) }
|
||||
func Benchmark_ZFlat13(b *testing.B) { benchFile(b, 13, false) }
|
||||
func Benchmark_ZFlat14(b *testing.B) { benchFile(b, 14, false) }
|
||||
func Benchmark_ZFlat15(b *testing.B) { benchFile(b, 15, false) }
|
||||
func Benchmark_ZFlat16(b *testing.B) { benchFile(b, 16, false) }
|
||||
func Benchmark_ZFlat17(b *testing.B) { benchFile(b, 17, false) }
|
||||
1
Godeps/_workspace/src/github.com/bkaradzic/go-lz4/.gitignore
generated
vendored
Normal file
1
Godeps/_workspace/src/github.com/bkaradzic/go-lz4/.gitignore
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/lz4-example/lz4-example
|
||||
7
Godeps/_workspace/src/github.com/bkaradzic/go-lz4/.travis.yml
generated
vendored
Normal file
7
Godeps/_workspace/src/github.com/bkaradzic/go-lz4/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.1
|
||||
- 1.2
|
||||
- 1.3
|
||||
- tip
|
||||
24
Godeps/_workspace/src/github.com/bkaradzic/go-lz4/LICENSE
generated
vendored
Normal file
24
Godeps/_workspace/src/github.com/bkaradzic/go-lz4/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
Copyright 2011-2012 Branimir Karadzic. All rights reserved.
|
||||
Copyright 2013 Damian Gryski. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
SHALL COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
71
Godeps/_workspace/src/github.com/bkaradzic/go-lz4/README.md
generated
vendored
Normal file
71
Godeps/_workspace/src/github.com/bkaradzic/go-lz4/README.md
generated
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
go-lz4
|
||||
======
|
||||
|
||||
go-lz4 is port of LZ4 lossless compression algorithm to Go. The original C code
|
||||
is located at:
|
||||
|
||||
https://code.google.com/p/lz4/
|
||||
|
||||
Status
|
||||
------
|
||||
[](http://travis-ci.org/bkaradzic/go-lz4)
|
||||
[](https://godoc.org/github.com/bkaradzic/go-lz4)
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
go get github.com/bkaradzic/go-lz4
|
||||
|
||||
import "github.com/bkaradzic/go-lz4"
|
||||
|
||||
The package name is `lz4`
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
* go-lz4 saves a uint32 with the original uncompressed length at the beginning
|
||||
of the encoded buffer. They may get in the way of interoperability with
|
||||
other implementations.
|
||||
|
||||
Contributors
|
||||
------------
|
||||
|
||||
Damian Gryski ([@dgryski](https://github.com/dgryski))
|
||||
Dustin Sallings ([@dustin](https://github.com/dustin))
|
||||
|
||||
Contact
|
||||
-------
|
||||
|
||||
[@bkaradzic](https://twitter.com/bkaradzic)
|
||||
http://www.stuckingeometry.com
|
||||
|
||||
Project page
|
||||
https://github.com/bkaradzic/go-lz4
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
Copyright 2011-2012 Branimir Karadzic. All rights reserved.
|
||||
Copyright 2013 Damian Gryski. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
SHALL COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
74
Godeps/_workspace/src/github.com/bkaradzic/go-lz4/fuzzer/main.go
generated
vendored
Normal file
74
Godeps/_workspace/src/github.com/bkaradzic/go-lz4/fuzzer/main.go
generated
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
|
||||
"github.com/bkaradzic/go-lz4"
|
||||
|
||||
// lz4's API matches snappy's, so we can easily see how it performs
|
||||
// lz4 "code.google.com/p/snappy-go/snappy"
|
||||
)
|
||||
|
||||
var input = `
|
||||
ADVENTURE I. A SCANDAL IN BOHEMIA
|
||||
|
||||
I.
|
||||
|
||||
To Sherlock Holmes she is always THE woman. I have seldom heard
|
||||
him mention her under any other name. In his eyes she eclipses
|
||||
and predominates the whole of her sex. It was not that he felt
|
||||
any emotion akin to love for Irene Adler. All emotions, and that
|
||||
one particularly, were abhorrent to his cold, precise but
|
||||
admirably balanced mind. He was, I take it, the most perfect
|
||||
reasoning and observing machine that the world has seen, but as a
|
||||
lover he would have placed himself in a false position. He never
|
||||
spoke of the softer passions, save with a gibe and a sneer. They
|
||||
were admirable things for the observer--excellent for drawing the
|
||||
veil from men's motives and actions. But for the trained reasoner
|
||||
to admit such intrusions into his own delicate and finely
|
||||
adjusted temperament was to introduce a distracting factor which
|
||||
might throw a doubt upon all his mental results. Grit in a
|
||||
sensitive instrument, or a crack in one of his own high-power
|
||||
lenses, would not be more disturbing than a strong emotion in a
|
||||
nature such as his. And yet there was but one woman to him, and
|
||||
that woman was the late Irene Adler, of dubious and questionable
|
||||
memory.
|
||||
|
||||
I had seen little of Holmes lately. My marriage had drifted us
|
||||
away from each other. My own complete happiness, and the
|
||||
home-centred interests which rise up around the man who first
|
||||
finds himself master of his own establishment, were sufficient to
|
||||
absorb all my attention, while Holmes, who loathed every form of
|
||||
society with his whole Bohemian soul, remained in our lodgings in
|
||||
Baker Street, buried among his old books, and alternating from
|
||||
week to week between cocaine and ambition, the drowsiness of the
|
||||
drug, and the fierce energy of his own keen nature. He was still,
|
||||
as ever, deeply attracted by the study of crime, and occupied his
|
||||
immense faculties and extraordinary powers of observation in
|
||||
following out those clues, and clearing up those mysteries which
|
||||
had been abandoned as hopeless by the official police. From time
|
||||
to time I heard some vague account of his doings: of his summons
|
||||
to Odessa in the case of the Trepoff murder, of his clearing up
|
||||
of the singular tragedy of the Atkinson brothers at Trincomalee,
|
||||
and finally of the mission which he had accomplished so
|
||||
delicately and successfully for the reigning family of Holland.
|
||||
Beyond these signs of his activity, however, which I merely
|
||||
shared with all the readers of the daily press, I knew little of
|
||||
my former friend and companion.
|
||||
`
|
||||
|
||||
func main() {
|
||||
|
||||
compressed, _ := lz4.Encode(nil, []byte(input))
|
||||
|
||||
modified := make([]byte, len(compressed))
|
||||
|
||||
for {
|
||||
copy(modified, compressed)
|
||||
for i := 0; i < 100; i++ {
|
||||
modified[rand.Intn(len(compressed)-4)+4] = byte(rand.Intn(256))
|
||||
}
|
||||
lz4.Decode(nil, modified)
|
||||
}
|
||||
|
||||
}
|
||||
86
Godeps/_workspace/src/github.com/bkaradzic/go-lz4/lz4-example/main.go
generated
vendored
Normal file
86
Godeps/_workspace/src/github.com/bkaradzic/go-lz4/lz4-example/main.go
generated
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2011 Branimir Karadzic. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"runtime/pprof"
|
||||
|
||||
lz4 "github.com/bkaradzic/go-lz4"
|
||||
)
|
||||
|
||||
var (
|
||||
decompress = flag.Bool("d", false, "decompress")
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
var optCPUProfile = flag.String("cpuprofile", "", "profile")
|
||||
flag.Parse()
|
||||
|
||||
if *optCPUProfile != "" {
|
||||
f, err := os.Create(*optCPUProfile)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
pprof.StartCPUProfile(f)
|
||||
defer pprof.StopCPUProfile()
|
||||
}
|
||||
|
||||
args := flag.Args()
|
||||
|
||||
var data []byte
|
||||
|
||||
if len(args) < 2 {
|
||||
fmt.Print("Usage: lz4 [-d] <input> <output>\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
input, err := os.OpenFile(args[0], os.O_RDONLY, 0644)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to open input file %s\n", args[0])
|
||||
os.Exit(1)
|
||||
}
|
||||
defer input.Close()
|
||||
|
||||
if *decompress {
|
||||
data, _ = ioutil.ReadAll(input)
|
||||
data, _ = lz4.Decode(nil, data)
|
||||
} else {
|
||||
data, _ = ioutil.ReadAll(input)
|
||||
data, _ = lz4.Encode(nil, data)
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile(args[1], data, 0644)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to open output file %s\n", args[1])
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
63
Godeps/_workspace/src/github.com/bkaradzic/go-lz4/lz4_test.go
generated
vendored
Normal file
63
Godeps/_workspace/src/github.com/bkaradzic/go-lz4/lz4_test.go
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
package lz4
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var testfile, _ = ioutil.ReadFile("testdata/pg1661.txt")
|
||||
|
||||
func roundtrip(t *testing.T, input []byte) {
|
||||
|
||||
dst, err := Encode(nil, input)
|
||||
if err != nil {
|
||||
t.Errorf("got error during compression: %s", err)
|
||||
}
|
||||
|
||||
output, err := Decode(nil, dst)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("got error during decompress: %s", err)
|
||||
}
|
||||
|
||||
if !bytes.Equal(output, input) {
|
||||
t.Errorf("roundtrip failed")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmpty(t *testing.T) {
|
||||
roundtrip(t, nil)
|
||||
}
|
||||
|
||||
func TestLengths(t *testing.T) {
|
||||
|
||||
for i := 0; i < 1024; i++ {
|
||||
roundtrip(t, testfile[:i])
|
||||
}
|
||||
|
||||
for i := 1024; i < 4096; i += 23 {
|
||||
roundtrip(t, testfile[:i])
|
||||
}
|
||||
}
|
||||
|
||||
func TestWords(t *testing.T) {
|
||||
roundtrip(t, testfile)
|
||||
}
|
||||
|
||||
func BenchmarkLZ4Encode(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
Encode(nil, testfile)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkLZ4Decode(b *testing.B) {
|
||||
|
||||
var compressed, _ = Encode(nil, testfile)
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
Decode(nil, compressed)
|
||||
}
|
||||
}
|
||||
194
Godeps/_workspace/src/github.com/bkaradzic/go-lz4/reader.go
generated
vendored
Normal file
194
Godeps/_workspace/src/github.com/bkaradzic/go-lz4/reader.go
generated
vendored
Normal file
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Copyright 2011-2012 Branimir Karadzic. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package lz4
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"io"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrCorrupt indicates the input was corrupt
|
||||
ErrCorrupt = errors.New("corrupt input")
|
||||
)
|
||||
|
||||
const (
|
||||
mlBits = 4
|
||||
mlMask = (1 << mlBits) - 1
|
||||
runBits = 8 - mlBits
|
||||
runMask = (1 << runBits) - 1
|
||||
)
|
||||
|
||||
type decoder struct {
|
||||
src []byte
|
||||
dst []byte
|
||||
spos uint32
|
||||
dpos uint32
|
||||
ref uint32
|
||||
}
|
||||
|
||||
func (d *decoder) readByte() (uint8, error) {
|
||||
if int(d.spos) == len(d.src) {
|
||||
return 0, io.EOF
|
||||
}
|
||||
b := d.src[d.spos]
|
||||
d.spos++
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func (d *decoder) getLen() (uint32, error) {
|
||||
|
||||
length := uint32(0)
|
||||
ln, err := d.readByte()
|
||||
if err != nil {
|
||||
return 0, ErrCorrupt
|
||||
}
|
||||
for ln == 255 {
|
||||
length += 255
|
||||
ln, err = d.readByte()
|
||||
if err != nil {
|
||||
return 0, ErrCorrupt
|
||||
}
|
||||
}
|
||||
length += uint32(ln)
|
||||
|
||||
return length, nil
|
||||
}
|
||||
|
||||
func (d *decoder) cp(length, decr uint32) {
|
||||
|
||||
if int(d.ref+length) < int(d.dpos) {
|
||||
copy(d.dst[d.dpos:], d.dst[d.ref:d.ref+length])
|
||||
} else {
|
||||
for ii := uint32(0); ii < length; ii++ {
|
||||
d.dst[d.dpos+ii] = d.dst[d.ref+ii]
|
||||
}
|
||||
}
|
||||
d.dpos += length
|
||||
d.ref += length - decr
|
||||
}
|
||||
|
||||
func (d *decoder) finish(err error) error {
|
||||
if err == io.EOF {
|
||||
return nil
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// Decode returns the decoded form of src. The returned slice may be a
|
||||
// subslice of dst if it was large enough to hold the entire decoded block.
|
||||
func Decode(dst, src []byte) ([]byte, error) {
|
||||
|
||||
if len(src) < 4 {
|
||||
return nil, ErrCorrupt
|
||||
}
|
||||
|
||||
uncompressedLen := binary.LittleEndian.Uint32(src)
|
||||
|
||||
if uncompressedLen == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if uncompressedLen > MaxInputSize {
|
||||
return nil, ErrTooLarge
|
||||
}
|
||||
|
||||
if dst == nil || len(dst) < int(uncompressedLen) {
|
||||
dst = make([]byte, uncompressedLen)
|
||||
}
|
||||
|
||||
d := decoder{src: src, dst: dst[:uncompressedLen], spos: 4}
|
||||
|
||||
decr := []uint32{0, 3, 2, 3}
|
||||
|
||||
for {
|
||||
code, err := d.readByte()
|
||||
if err != nil {
|
||||
return d.dst, d.finish(err)
|
||||
}
|
||||
|
||||
length := uint32(code >> mlBits)
|
||||
if length == runMask {
|
||||
ln, err := d.getLen()
|
||||
if err != nil {
|
||||
return nil, ErrCorrupt
|
||||
}
|
||||
length += ln
|
||||
}
|
||||
|
||||
if int(d.spos+length) > len(d.src) {
|
||||
return nil, ErrCorrupt
|
||||
}
|
||||
|
||||
for ii := uint32(0); ii < length; ii++ {
|
||||
d.dst[d.dpos+ii] = d.src[d.spos+ii]
|
||||
}
|
||||
|
||||
d.spos += length
|
||||
d.dpos += length
|
||||
|
||||
if int(d.spos) == len(d.src) {
|
||||
return d.dst, nil
|
||||
}
|
||||
|
||||
if int(d.spos+2) >= len(d.src) {
|
||||
return nil, ErrCorrupt
|
||||
}
|
||||
|
||||
back := uint32(d.src[d.spos]) | uint32(d.src[d.spos+1])<<8
|
||||
|
||||
if back > d.dpos {
|
||||
return nil, ErrCorrupt
|
||||
}
|
||||
|
||||
d.spos += 2
|
||||
d.ref = d.dpos - back
|
||||
|
||||
length = uint32(code & mlMask)
|
||||
if length == mlMask {
|
||||
ln, err := d.getLen()
|
||||
if err != nil {
|
||||
return nil, ErrCorrupt
|
||||
}
|
||||
length += ln
|
||||
}
|
||||
|
||||
literal := d.dpos - d.ref
|
||||
if literal < 4 {
|
||||
d.cp(4, decr[literal])
|
||||
} else {
|
||||
length += 4
|
||||
}
|
||||
|
||||
if d.dpos+length > uncompressedLen {
|
||||
return nil, ErrCorrupt
|
||||
}
|
||||
|
||||
d.cp(length, 0)
|
||||
}
|
||||
}
|
||||
13052
Godeps/_workspace/src/github.com/bkaradzic/go-lz4/testdata/pg1661.txt
generated
vendored
Normal file
13052
Godeps/_workspace/src/github.com/bkaradzic/go-lz4/testdata/pg1661.txt
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
188
Godeps/_workspace/src/github.com/bkaradzic/go-lz4/writer.go
generated
vendored
Normal file
188
Godeps/_workspace/src/github.com/bkaradzic/go-lz4/writer.go
generated
vendored
Normal file
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* Copyright 2011-2012 Branimir Karadzic. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package lz4
|
||||
|
||||
import "encoding/binary"
|
||||
import "errors"
|
||||
|
||||
const (
|
||||
minMatch = 4
|
||||
hashLog = 17
|
||||
hashTableSize = 1 << hashLog
|
||||
hashShift = (minMatch * 8) - hashLog
|
||||
incompressible uint32 = 128
|
||||
uninitHash = 0x88888888
|
||||
|
||||
// MaxInputSize is the largest buffer than can be compressed in a single block
|
||||
MaxInputSize = 0x7E000000
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrTooLarge indicates the input buffer was too large
|
||||
ErrTooLarge = errors.New("input too large")
|
||||
)
|
||||
|
||||
type encoder struct {
|
||||
src []byte
|
||||
dst []byte
|
||||
hashTable []uint32
|
||||
pos uint32
|
||||
anchor uint32
|
||||
dpos uint32
|
||||
}
|
||||
|
||||
// CompressBound returns the maximum length of a lz4 block, given it's uncompressed length
|
||||
func CompressBound(isize int) int {
|
||||
if isize > MaxInputSize {
|
||||
return 0
|
||||
}
|
||||
return isize + ((isize) / 255) + 16 + 4
|
||||
}
|
||||
|
||||
func (e *encoder) writeLiterals(length, mlLen, pos uint32) {
|
||||
|
||||
ln := length
|
||||
|
||||
var code byte
|
||||
if ln > runMask-1 {
|
||||
code = runMask
|
||||
} else {
|
||||
code = byte(ln)
|
||||
}
|
||||
|
||||
if mlLen > mlMask-1 {
|
||||
e.dst[e.dpos] = (code << mlBits) + byte(mlMask)
|
||||
} else {
|
||||
e.dst[e.dpos] = (code << mlBits) + byte(mlLen)
|
||||
}
|
||||
e.dpos++
|
||||
|
||||
if code == runMask {
|
||||
ln -= runMask
|
||||
for ; ln > 254; ln -= 255 {
|
||||
e.dst[e.dpos] = 255
|
||||
e.dpos++
|
||||
}
|
||||
|
||||
e.dst[e.dpos] = byte(ln)
|
||||
e.dpos++
|
||||
}
|
||||
|
||||
for ii := uint32(0); ii < length; ii++ {
|
||||
e.dst[e.dpos+ii] = e.src[pos+ii]
|
||||
}
|
||||
|
||||
e.dpos += length
|
||||
}
|
||||
|
||||
// Encode returns the encoded form of src. The returned array may be a
|
||||
// sub-slice of dst if it was large enough to hold the entire output.
|
||||
func Encode(dst, src []byte) ([]byte, error) {
|
||||
|
||||
if len(src) >= MaxInputSize {
|
||||
return nil, ErrTooLarge
|
||||
}
|
||||
|
||||
if n := CompressBound(len(src)); len(dst) < n {
|
||||
dst = make([]byte, n)
|
||||
}
|
||||
|
||||
e := encoder{src: src, dst: dst, hashTable: make([]uint32, hashTableSize)}
|
||||
|
||||
binary.LittleEndian.PutUint32(dst, uint32(len(src)))
|
||||
e.dpos = 4
|
||||
|
||||
var (
|
||||
step uint32 = 1
|
||||
limit = incompressible
|
||||
)
|
||||
|
||||
for {
|
||||
if int(e.pos)+4 >= len(e.src) {
|
||||
e.writeLiterals(uint32(len(e.src))-e.anchor, 0, e.anchor)
|
||||
return e.dst[:e.dpos], nil
|
||||
}
|
||||
|
||||
sequence := uint32(e.src[e.pos+3])<<24 | uint32(e.src[e.pos+2])<<16 | uint32(e.src[e.pos+1])<<8 | uint32(e.src[e.pos+0])
|
||||
|
||||
hash := (sequence * 2654435761) >> hashShift
|
||||
ref := e.hashTable[hash] + uninitHash
|
||||
e.hashTable[hash] = e.pos - uninitHash
|
||||
|
||||
if ((e.pos-ref)>>16) != 0 || uint32(e.src[ref+3])<<24|uint32(e.src[ref+2])<<16|uint32(e.src[ref+1])<<8|uint32(e.src[ref+0]) != sequence {
|
||||
if e.pos-e.anchor > limit {
|
||||
limit <<= 1
|
||||
step += 1 + (step >> 2)
|
||||
}
|
||||
e.pos += step
|
||||
continue
|
||||
}
|
||||
|
||||
if step > 1 {
|
||||
e.hashTable[hash] = ref - uninitHash
|
||||
e.pos -= step - 1
|
||||
step = 1
|
||||
continue
|
||||
}
|
||||
limit = incompressible
|
||||
|
||||
ln := e.pos - e.anchor
|
||||
back := e.pos - ref
|
||||
|
||||
anchor := e.anchor
|
||||
|
||||
e.pos += minMatch
|
||||
ref += minMatch
|
||||
e.anchor = e.pos
|
||||
|
||||
for int(e.pos) < len(e.src) && e.src[e.pos] == e.src[ref] {
|
||||
e.pos++
|
||||
ref++
|
||||
}
|
||||
|
||||
mlLen := e.pos - e.anchor
|
||||
|
||||
e.writeLiterals(ln, mlLen, anchor)
|
||||
e.dst[e.dpos] = uint8(back)
|
||||
e.dst[e.dpos+1] = uint8(back >> 8)
|
||||
e.dpos += 2
|
||||
|
||||
if mlLen > mlMask-1 {
|
||||
mlLen -= mlMask
|
||||
for mlLen > 254 {
|
||||
mlLen -= 255
|
||||
|
||||
e.dst[e.dpos] = 255
|
||||
e.dpos++
|
||||
}
|
||||
|
||||
e.dst[e.dpos] = byte(mlLen)
|
||||
e.dpos++
|
||||
}
|
||||
|
||||
e.anchor = e.pos
|
||||
}
|
||||
}
|
||||
39
Godeps/_workspace/src/github.com/calmh/ini/README.md
generated
vendored
39
Godeps/_workspace/src/github.com/calmh/ini/README.md
generated
vendored
@@ -1,39 +0,0 @@
|
||||
ini [](https://drone.io/github.com/calmh/ini/latest)
|
||||
===
|
||||
|
||||
Yet another .INI file parser / writer. Created because the existing ones
|
||||
were either not general enough (allowing easy access to all parts of the
|
||||
original file) or made annoying assumptions about the format. And
|
||||
probably equal parts NIH. You might want to just write your own instead
|
||||
of using this one, you know that's where you'll end up in the end
|
||||
anyhow.
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
http://godoc.org/github.com/calmh/ini
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
```go
|
||||
fd, _ := os.Open("foo.ini")
|
||||
cfg := ini.Parse(fd)
|
||||
fd.Close()
|
||||
|
||||
val := cfg.Get("general", "foo")
|
||||
cfg.Set("general", "bar", "baz")
|
||||
|
||||
fd, _ = os.Create("bar.ini")
|
||||
err := cfg.Write(fd)
|
||||
if err != nil {
|
||||
// ...
|
||||
}
|
||||
err = fd.Close()
|
||||
|
||||
```
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
MIT
|
||||
235
Godeps/_workspace/src/github.com/calmh/ini/ini.go
generated
vendored
235
Godeps/_workspace/src/github.com/calmh/ini/ini.go
generated
vendored
@@ -1,235 +0,0 @@
|
||||
// Package ini provides trivial parsing of .INI format files.
|
||||
package ini
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Config is a parsed INI format file.
|
||||
type Config struct {
|
||||
sections []section
|
||||
comments []string
|
||||
}
|
||||
|
||||
type section struct {
|
||||
name string
|
||||
comments []string
|
||||
options []option
|
||||
}
|
||||
|
||||
type option struct {
|
||||
name, value string
|
||||
}
|
||||
|
||||
var (
|
||||
iniSectionRe = regexp.MustCompile(`^\[(.+)\]$`)
|
||||
iniOptionRe = regexp.MustCompile(`^([^\s=]+)\s*=\s*(.+?)$`)
|
||||
)
|
||||
|
||||
// Sections returns the list of sections in the file.
|
||||
func (c *Config) Sections() []string {
|
||||
var sections []string
|
||||
for _, sect := range c.sections {
|
||||
sections = append(sections, sect.name)
|
||||
}
|
||||
return sections
|
||||
}
|
||||
|
||||
// Options returns the list of options in a given section.
|
||||
func (c *Config) Options(section string) []string {
|
||||
var options []string
|
||||
for _, sect := range c.sections {
|
||||
if sect.name == section {
|
||||
for _, opt := range sect.options {
|
||||
options = append(options, opt.name)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
return options
|
||||
}
|
||||
|
||||
// OptionMap returns the map option => value for a given section.
|
||||
func (c *Config) OptionMap(section string) map[string]string {
|
||||
options := make(map[string]string)
|
||||
for _, sect := range c.sections {
|
||||
if sect.name == section {
|
||||
for _, opt := range sect.options {
|
||||
options[opt.name] = opt.value
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
return options
|
||||
}
|
||||
|
||||
// Comments returns the list of comments in a given section.
|
||||
// For the empty string, returns the file comments.
|
||||
func (c *Config) Comments(section string) []string {
|
||||
if section == "" {
|
||||
return c.comments
|
||||
}
|
||||
for _, sect := range c.sections {
|
||||
if sect.name == section {
|
||||
return sect.comments
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddComments appends the comment to the list of comments for the section.
|
||||
func (c *Config) AddComment(sect, comment string) {
|
||||
if sect == "" {
|
||||
c.comments = append(c.comments, comment)
|
||||
return
|
||||
}
|
||||
|
||||
for i, s := range c.sections {
|
||||
if s.name == sect {
|
||||
c.sections[i].comments = append(s.comments, comment)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
c.sections = append(c.sections, section{
|
||||
name: sect,
|
||||
comments: []string{comment},
|
||||
})
|
||||
}
|
||||
|
||||
// Parse reads the given io.Reader and returns a parsed Config object.
|
||||
func Parse(stream io.Reader) Config {
|
||||
var cfg Config
|
||||
var curSection string
|
||||
|
||||
scanner := bufio.NewScanner(bufio.NewReader(stream))
|
||||
for scanner.Scan() {
|
||||
line := strings.TrimSpace(scanner.Text())
|
||||
if strings.HasPrefix(line, "#") || strings.HasPrefix(line, ";") {
|
||||
comment := strings.TrimLeft(line, ";# ")
|
||||
cfg.AddComment(curSection, comment)
|
||||
} else if len(line) > 0 {
|
||||
if m := iniSectionRe.FindStringSubmatch(line); len(m) > 0 {
|
||||
curSection = m[1]
|
||||
} else if m := iniOptionRe.FindStringSubmatch(line); len(m) > 0 {
|
||||
key := m[1]
|
||||
val := m[2]
|
||||
if !strings.Contains(val, "\"") {
|
||||
// If val does not contain any quote characers, we can make it
|
||||
// a quoted string and safely let strconv.Unquote sort out any
|
||||
// escapes
|
||||
val = "\"" + val + "\""
|
||||
}
|
||||
if val[0] == '"' {
|
||||
val, _ = strconv.Unquote(val)
|
||||
}
|
||||
|
||||
cfg.Set(curSection, key, val)
|
||||
}
|
||||
}
|
||||
}
|
||||
return cfg
|
||||
}
|
||||
|
||||
// Write writes the sections and options to the io.Writer in INI format.
|
||||
func (c *Config) Write(out io.Writer) error {
|
||||
for _, cmt := range c.comments {
|
||||
fmt.Fprintln(out, "; "+cmt)
|
||||
}
|
||||
if len(c.comments) > 0 {
|
||||
fmt.Fprintln(out)
|
||||
}
|
||||
|
||||
for _, sect := range c.sections {
|
||||
fmt.Fprintf(out, "[%s]\n", sect.name)
|
||||
for _, cmt := range sect.comments {
|
||||
fmt.Fprintln(out, "; "+cmt)
|
||||
}
|
||||
for _, opt := range sect.options {
|
||||
val := opt.value
|
||||
if len(val) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// Quote the string if it begins or ends with space
|
||||
needsQuoting := val[0] == ' ' || val[len(val)-1] == ' '
|
||||
|
||||
if !needsQuoting {
|
||||
// Quote the string if it contains any unprintable characters
|
||||
for _, r := range val {
|
||||
if !strconv.IsPrint(r) {
|
||||
needsQuoting = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if needsQuoting {
|
||||
val = strconv.Quote(val)
|
||||
}
|
||||
|
||||
fmt.Fprintf(out, "%s=%s\n", opt.name, val)
|
||||
}
|
||||
fmt.Fprintln(out)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get gets the value from the specified section and key name, or the empty
|
||||
// string if either the section or the key is missing.
|
||||
func (c *Config) Get(section, key string) string {
|
||||
for _, sect := range c.sections {
|
||||
if sect.name == section {
|
||||
for _, opt := range sect.options {
|
||||
if opt.name == key {
|
||||
return opt.value
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// Set sets a value for an option in a section. If the option exists, it's
|
||||
// value will be overwritten. If the option does not exist, it will be added.
|
||||
// If the section does not exist, it will be added and the option added to it.
|
||||
func (c *Config) Set(sectionName, key, value string) {
|
||||
for i, sect := range c.sections {
|
||||
if sect.name == sectionName {
|
||||
for j, opt := range sect.options {
|
||||
if opt.name == key {
|
||||
c.sections[i].options[j].value = value
|
||||
return
|
||||
}
|
||||
}
|
||||
c.sections[i].options = append(sect.options, option{key, value})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
c.sections = append(c.sections, section{
|
||||
name: sectionName,
|
||||
options: []option{{key, value}},
|
||||
})
|
||||
}
|
||||
|
||||
// Delete removes the option from the specified section.
|
||||
func (c *Config) Delete(section, key string) {
|
||||
for sn, sect := range c.sections {
|
||||
if sect.name == section {
|
||||
for i, opt := range sect.options {
|
||||
if opt.name == key {
|
||||
c.sections[sn].options = append(sect.options[:i], sect.options[i+1:]...)
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
214
Godeps/_workspace/src/github.com/calmh/ini/ini_test.go
generated
vendored
214
Godeps/_workspace/src/github.com/calmh/ini/ini_test.go
generated
vendored
@@ -1,214 +0,0 @@
|
||||
package ini_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/calmh/ini"
|
||||
)
|
||||
|
||||
func TestParseValues(t *testing.T) {
|
||||
strs := []string{
|
||||
`[general]`,
|
||||
`k1=v1`,
|
||||
`k2 = v2`,
|
||||
` k3 = v3 `,
|
||||
`k4=" quoted spaces "`,
|
||||
`k5 = " quoted spaces " `,
|
||||
`k6 = with\nnewline`,
|
||||
`k7 = "with\nnewline"`,
|
||||
`k8 = a "quoted" word`,
|
||||
`k9 = "a \"quoted\" word"`,
|
||||
}
|
||||
buf := bytes.NewBufferString(strings.Join(strs, "\n"))
|
||||
cfg := ini.Parse(buf)
|
||||
|
||||
correct := map[string]string{
|
||||
"k1": "v1",
|
||||
"k2": "v2",
|
||||
"k3": "v3",
|
||||
"k4": " quoted spaces ",
|
||||
"k5": " quoted spaces ",
|
||||
"k6": "with\nnewline",
|
||||
"k7": "with\nnewline",
|
||||
"k8": "a \"quoted\" word",
|
||||
"k9": "a \"quoted\" word",
|
||||
}
|
||||
|
||||
for k, v := range correct {
|
||||
if v2 := cfg.Get("general", k); v2 != v {
|
||||
t.Errorf("Incorrect general.%s, %q != %q", k, v2, v)
|
||||
}
|
||||
}
|
||||
|
||||
if v := cfg.Get("general", "nonexistant"); v != "" {
|
||||
t.Errorf("Unexpected non-empty value %q", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseComments(t *testing.T) {
|
||||
strs := []string{
|
||||
";file comment 1", // No leading space
|
||||
"; file comment 2 ", // Trailing space
|
||||
"; file comment 3", // Multiple leading spaces
|
||||
"[general]",
|
||||
"; b general comment 1", // Comments in unsorted order
|
||||
"somekey = somevalue",
|
||||
"; a general comment 2",
|
||||
"[other]",
|
||||
"; other comment 1", // Comments in section with no values
|
||||
"; other comment 2",
|
||||
"[other2]",
|
||||
"; other2 comment 1",
|
||||
"; other2 comment 2", // Comments on last section
|
||||
"somekey = somevalue",
|
||||
}
|
||||
buf := bytes.NewBufferString(strings.Join(strs, "\n"))
|
||||
|
||||
correct := map[string][]string{
|
||||
"": []string{"file comment 1", "file comment 2", "file comment 3"},
|
||||
"general": []string{"b general comment 1", "a general comment 2"},
|
||||
"other": []string{"other comment 1", "other comment 2"},
|
||||
"other2": []string{"other2 comment 1", "other2 comment 2"},
|
||||
}
|
||||
|
||||
cfg := ini.Parse(buf)
|
||||
|
||||
for section, comments := range correct {
|
||||
cmts := cfg.Comments(section)
|
||||
if len(cmts) != len(comments) {
|
||||
t.Errorf("Incorrect number of comments for section %q: %d != %d", section, len(cmts), len(comments))
|
||||
} else {
|
||||
for i := range comments {
|
||||
if cmts[i] != comments[i] {
|
||||
t.Errorf("Incorrect comment: %q != %q", cmts[i], comments[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestWrite(t *testing.T) {
|
||||
cfg := ini.Config{}
|
||||
cfg.Set("general", "k1", "v1")
|
||||
cfg.Set("general", "k2", "foo bar")
|
||||
cfg.Set("general", "k3", " foo bar ")
|
||||
cfg.Set("general", "k4", "foo\nbar")
|
||||
|
||||
var out bytes.Buffer
|
||||
cfg.Write(&out)
|
||||
|
||||
correct := `[general]
|
||||
k1=v1
|
||||
k2=foo bar
|
||||
k3=" foo bar "
|
||||
k4="foo\nbar"
|
||||
|
||||
`
|
||||
if s := out.String(); s != correct {
|
||||
t.Errorf("Incorrect written .INI:\n%s\ncorrect:\n%s", s, correct)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSet(t *testing.T) {
|
||||
buf := bytes.NewBufferString("[general]\nfoo=bar\nfoo2=bar2\n")
|
||||
cfg := ini.Parse(buf)
|
||||
|
||||
cfg.Set("general", "foo", "baz") // Overwrite existing
|
||||
cfg.Set("general", "baz", "quux") // Create new value
|
||||
cfg.Set("other", "baz2", "quux2") // Create new section + value
|
||||
|
||||
var out bytes.Buffer
|
||||
cfg.Write(&out)
|
||||
|
||||
correct := `[general]
|
||||
foo=baz
|
||||
foo2=bar2
|
||||
baz=quux
|
||||
|
||||
[other]
|
||||
baz2=quux2
|
||||
|
||||
`
|
||||
|
||||
if s := out.String(); s != correct {
|
||||
t.Errorf("Incorrect INI after set:\n%s", s)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDelete(t *testing.T) {
|
||||
buf := bytes.NewBufferString("[general]\nfoo=bar\nfoo2=bar2\nfoo3=baz\n")
|
||||
cfg := ini.Parse(buf)
|
||||
cfg.Delete("general", "foo")
|
||||
out := new(bytes.Buffer)
|
||||
cfg.Write(out)
|
||||
correct := "[general]\nfoo2=bar2\nfoo3=baz\n\n"
|
||||
|
||||
if s := out.String(); s != correct {
|
||||
t.Errorf("Incorrect INI after delete:\n%s", s)
|
||||
}
|
||||
|
||||
buf = bytes.NewBufferString("[general]\nfoo=bar\nfoo2=bar2\nfoo3=baz\n")
|
||||
cfg = ini.Parse(buf)
|
||||
cfg.Delete("general", "foo2")
|
||||
out = new(bytes.Buffer)
|
||||
cfg.Write(out)
|
||||
correct = "[general]\nfoo=bar\nfoo3=baz\n\n"
|
||||
|
||||
if s := out.String(); s != correct {
|
||||
t.Errorf("Incorrect INI after delete:\n%s", s)
|
||||
}
|
||||
|
||||
buf = bytes.NewBufferString("[general]\nfoo=bar\nfoo2=bar2\nfoo3=baz\n")
|
||||
cfg = ini.Parse(buf)
|
||||
cfg.Delete("general", "foo3")
|
||||
out = new(bytes.Buffer)
|
||||
cfg.Write(out)
|
||||
correct = "[general]\nfoo=bar\nfoo2=bar2\n\n"
|
||||
|
||||
if s := out.String(); s != correct {
|
||||
t.Errorf("Incorrect INI after delete:\n%s", s)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetManyEquals(t *testing.T) {
|
||||
buf := bytes.NewBufferString("[general]\nfoo=bar==\nfoo2=bar2==\n")
|
||||
cfg := ini.Parse(buf)
|
||||
|
||||
cfg.Set("general", "foo", "baz==")
|
||||
|
||||
var out bytes.Buffer
|
||||
cfg.Write(&out)
|
||||
|
||||
correct := `[general]
|
||||
foo=baz==
|
||||
foo2=bar2==
|
||||
|
||||
`
|
||||
|
||||
if s := out.String(); s != correct {
|
||||
t.Errorf("Incorrect INI after set:\n%s", s)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRewriteDuplicate(t *testing.T) {
|
||||
buf := bytes.NewBufferString("[general]\nfoo=bar==\nfoo=bar2==\n")
|
||||
cfg := ini.Parse(buf)
|
||||
|
||||
if v := cfg.Get("general", "foo"); v != "bar2==" {
|
||||
t.Errorf("incorrect get %q", v)
|
||||
}
|
||||
|
||||
var out bytes.Buffer
|
||||
cfg.Write(&out)
|
||||
|
||||
correct := `[general]
|
||||
foo=bar2==
|
||||
|
||||
`
|
||||
|
||||
if s := out.String(); s != correct {
|
||||
t.Errorf("Incorrect INI after set:\n%s", s)
|
||||
}
|
||||
}
|
||||
1
Godeps/_workspace/src/github.com/calmh/xdr/.gitignore
generated
vendored
Normal file
1
Godeps/_workspace/src/github.com/calmh/xdr/.gitignore
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
coverage.out
|
||||
19
Godeps/_workspace/src/github.com/calmh/xdr/.travis.yml
generated
vendored
Normal file
19
Godeps/_workspace/src/github.com/calmh/xdr/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
language: go
|
||||
go:
|
||||
- tip
|
||||
|
||||
install:
|
||||
- export PATH=$PATH:$HOME/gopath/bin
|
||||
- go get code.google.com/p/go.tools/cmd/cover
|
||||
- go get github.com/mattn/goveralls
|
||||
|
||||
script:
|
||||
- ./generate.sh
|
||||
- go test -coverprofile=coverage.out
|
||||
|
||||
after_success:
|
||||
- goveralls -coverprofile=coverage.out -service=travis-ci -package=calmh/xdr -repotoken="$COVERALLS_TOKEN"
|
||||
|
||||
env:
|
||||
global:
|
||||
secure: SmgnrGfp2zLrA44ChRMpjPeujubt9veZ8Fx/OseMWECmacyV5N/TuDhzIbwo6QwV4xB0sBacoPzvxQbJRVjNKsPiSu72UbcQmQ7flN4Tf7nW09tSh1iW8NgrpBCq/3UYLoBu2iPBEBKm93IK0aGNAKs6oEkB0fU27iTVBwiTXOY=
|
||||
@@ -1,11 +1,11 @@
|
||||
Copyright (C) 2013 Jakob Borg
|
||||
Copyright (C) 2014 Jakob Borg.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to
|
||||
deal in the Software without restriction, including without limitation the
|
||||
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
- The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
@@ -14,6 +14,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
IN THE SOFTWARE.
|
||||
12
Godeps/_workspace/src/github.com/calmh/xdr/README.md
generated
vendored
Normal file
12
Godeps/_workspace/src/github.com/calmh/xdr/README.md
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
xdr
|
||||
===
|
||||
|
||||
[](https://travis-ci.org/calmh/xdr)
|
||||
[](https://coveralls.io/r/calmh/xdr?branch=master)
|
||||
[](http://godoc.org/github.com/calmh/xdr)
|
||||
[](http://opensource.org/licenses/MIT)
|
||||
|
||||
This is an XDR encoding/decoding library. It uses code generation and
|
||||
not reflection. It supports the IPDR bastardized XDR format when built
|
||||
with `-tags ipdr`.
|
||||
|
||||
88
Godeps/_workspace/src/github.com/calmh/xdr/bench_test.go
generated
vendored
Normal file
88
Godeps/_workspace/src/github.com/calmh/xdr/bench_test.go
generated
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
// Copyright (C) 2014 Jakob Borg. All rights reserved. Use of this source code
|
||||
// is governed by an MIT-style license that can be found in the LICENSE file.
|
||||
|
||||
package xdr_test
|
||||
|
||||
import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type XDRBenchStruct struct {
|
||||
I1 uint64
|
||||
I2 uint32
|
||||
I3 uint16
|
||||
I4 uint8
|
||||
Bs0 []byte // max:128
|
||||
Bs1 []byte
|
||||
S0 string // max:128
|
||||
S1 string
|
||||
}
|
||||
|
||||
var res []byte // no to be optimized away
|
||||
var s = XDRBenchStruct{
|
||||
I1: 42,
|
||||
I2: 43,
|
||||
I3: 44,
|
||||
I4: 45,
|
||||
Bs0: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18},
|
||||
Bs1: []byte{11, 12, 13, 14, 15, 16, 17, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
|
||||
S0: "Hello World! String one.",
|
||||
S1: "Hello World! String two.",
|
||||
}
|
||||
var e = s.MarshalXDR()
|
||||
|
||||
func BenchmarkThisMarshal(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
res = s.MarshalXDR()
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkThisUnmarshal(b *testing.B) {
|
||||
var t XDRBenchStruct
|
||||
for i := 0; i < b.N; i++ {
|
||||
err := t.UnmarshalXDR(e)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkThisEncode(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, err := s.EncodeXDR(ioutil.Discard)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type repeatReader struct {
|
||||
data []byte
|
||||
}
|
||||
|
||||
func (r *repeatReader) Read(bs []byte) (n int, err error) {
|
||||
if len(bs) > len(r.data) {
|
||||
err = io.EOF
|
||||
}
|
||||
n = copy(bs, r.data)
|
||||
r.data = r.data[n:]
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (r *repeatReader) Reset(bs []byte) {
|
||||
r.data = bs
|
||||
}
|
||||
|
||||
func BenchmarkThisDecode(b *testing.B) {
|
||||
rr := &repeatReader{e}
|
||||
var t XDRBenchStruct
|
||||
for i := 0; i < b.N; i++ {
|
||||
err := t.DecodeXDR(rr)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
rr.Reset(e)
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user