diff --git a/p2p/discovery/mdns.go b/p2p/discovery/mdns.go index e3b51e0da71bd56f04a044a1ab51d9124af2acbc..3b206b9a33b95571c9131eca23eb9e31820c25cb 100644 --- a/p2p/discovery/mdns.go +++ b/p2p/discovery/mdns.go @@ -9,13 +9,13 @@ import ( "sync" "time" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" + manet "QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net" "github.com/cryptix/mdns" - ma "github.com/jbenet/go-multiaddr" - manet "github.com/jbenet/go-multiaddr-net" + logging "QmWRypnfEwrgH4k93KEHN5hng7VjKYkWmzDYRuTZeh2Mgh/go-log" "github.com/ipfs/go-libp2p/p2p/host" "github.com/ipfs/go-libp2p/p2p/peer" - logging "QmWRypnfEwrgH4k93KEHN5hng7VjKYkWmzDYRuTZeh2Mgh/go-log" ) var log = logging.Logger("mdns") diff --git a/p2p/host/basic/basic_host.go b/p2p/host/basic/basic_host.go index bbe3e3b719468c7666b656a5936ecaa0ed031f7c..6444fe998665cd174bcba2b7ac1c8b21b1e03915 100644 --- a/p2p/host/basic/basic_host.go +++ b/p2p/host/basic/basic_host.go @@ -4,9 +4,9 @@ import ( "io" logging "QmWRypnfEwrgH4k93KEHN5hng7VjKYkWmzDYRuTZeh2Mgh/go-log" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" metrics "github.com/ipfs/go-libp2p/p2p/metrics" mstream "github.com/ipfs/go-libp2p/p2p/metrics/stream" - ma "github.com/jbenet/go-multiaddr" goprocess "github.com/jbenet/goprocess" context "golang.org/x/net/context" diff --git a/p2p/host/basic/natmgr.go b/p2p/host/basic/natmgr.go index 3ebbd35f3e2852c1e7b59f3e9055db5897f83af3..6a9a9bdc7d67bb0db7703ea5f477a23c48d3fdf9 100644 --- a/p2p/host/basic/natmgr.go +++ b/p2p/host/basic/natmgr.go @@ -3,7 +3,7 @@ package basichost import ( "sync" - ma "github.com/jbenet/go-multiaddr" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" goprocess "github.com/jbenet/goprocess" context "golang.org/x/net/context" diff --git a/p2p/host/host.go b/p2p/host/host.go index 4f235456e74dc9b4f45f3057054e95e388fce7d9..be2ecb7902a8888b834dbbf20b8777d242126fbc 100644 --- a/p2p/host/host.go +++ b/p2p/host/host.go @@ -2,11 +2,11 @@ package host import ( logging "QmWRypnfEwrgH4k93KEHN5hng7VjKYkWmzDYRuTZeh2Mgh/go-log" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" metrics "github.com/ipfs/go-libp2p/p2p/metrics" inet "github.com/ipfs/go-libp2p/p2p/net" peer "github.com/ipfs/go-libp2p/p2p/peer" protocol "github.com/ipfs/go-libp2p/p2p/protocol" - ma "github.com/jbenet/go-multiaddr" context "golang.org/x/net/context" msmux "github.com/whyrusleeping/go-multistream" diff --git a/p2p/host/routed/routed.go b/p2p/host/routed/routed.go index 9e748ab8f9ea0ce45432e30851006d5e2740cf7f..87cd63dda4a98387d0aa96aa7af97319c3a508d0 100644 --- a/p2p/host/routed/routed.go +++ b/p2p/host/routed/routed.go @@ -5,7 +5,7 @@ import ( "time" logging "QmWRypnfEwrgH4k93KEHN5hng7VjKYkWmzDYRuTZeh2Mgh/go-log" - ma "github.com/jbenet/go-multiaddr" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" context "golang.org/x/net/context" lgbl "util/eventlog/loggables" diff --git a/p2p/nat/nat.go b/p2p/nat/nat.go index 3c29d4ee0866e0fb25f55d25541c20a3956723ff..fe3a52114eb53d36f629d3568d6ac16cdc8cbd45 100644 --- a/p2p/nat/nat.go +++ b/p2p/nat/nat.go @@ -8,14 +8,14 @@ import ( "sync" "time" - ma "github.com/jbenet/go-multiaddr" - manet "github.com/jbenet/go-multiaddr-net" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" + manet "QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net" + logging "QmWRypnfEwrgH4k93KEHN5hng7VjKYkWmzDYRuTZeh2Mgh/go-log" nat "github.com/fd/go-nat" goprocess "github.com/jbenet/goprocess" periodic "github.com/jbenet/goprocess/periodic" notifier "thirdparty/notifier" - logging "QmWRypnfEwrgH4k93KEHN5hng7VjKYkWmzDYRuTZeh2Mgh/go-log" ) var ( diff --git a/p2p/net/conn/conn.go b/p2p/net/conn/conn.go index a3a52f8638d3fe99f8462714ab20e1eed7177b75..ad74fa975f7f02a0c58f68467b8fa1c974b219df 100644 --- a/p2p/net/conn/conn.go +++ b/p2p/net/conn/conn.go @@ -6,15 +6,15 @@ import ( "net" "time" - mpool "github.com/jbenet/go-msgio/mpool" - ma "github.com/jbenet/go-multiaddr" - manet "github.com/jbenet/go-multiaddr-net" - context "golang.org/x/net/context" + logging "QmWRypnfEwrgH4k93KEHN5hng7VjKYkWmzDYRuTZeh2Mgh/go-log" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" + manet "QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net" ic "github.com/ipfs/go-libp2p/p2p/crypto" peer "github.com/ipfs/go-libp2p/p2p/peer" + mpool "github.com/jbenet/go-msgio/mpool" + context "golang.org/x/net/context" u "util" lgbl "util/eventlog/loggables" - logging "QmWRypnfEwrgH4k93KEHN5hng7VjKYkWmzDYRuTZeh2Mgh/go-log" ) var log = logging.Logger("conn") diff --git a/p2p/net/conn/dial.go b/p2p/net/conn/dial.go index 1f0435bfd6844b0fc3fdf8053ce84842fea53095..ab426ad93bf5785680681876dce6e8748b273089 100644 --- a/p2p/net/conn/dial.go +++ b/p2p/net/conn/dial.go @@ -5,8 +5,8 @@ import ( "math/rand" "strings" - ma "github.com/jbenet/go-multiaddr" - manet "github.com/jbenet/go-multiaddr-net" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" + manet "QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net" context "golang.org/x/net/context" lgbl "util/eventlog/loggables" diff --git a/p2p/net/conn/dial_test.go b/p2p/net/conn/dial_test.go index c680765d2415347d5657808953482acb6f65a0e2..956c493886fc2c963b129d40df833b2f1b32a875 100644 --- a/p2p/net/conn/dial_test.go +++ b/p2p/net/conn/dial_test.go @@ -13,7 +13,7 @@ import ( peer "github.com/ipfs/go-libp2p/p2p/peer" tu "util/testutil" - ma "github.com/jbenet/go-multiaddr" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" context "golang.org/x/net/context" ) diff --git a/p2p/net/conn/interface.go b/p2p/net/conn/interface.go index a2ccb732f4fa55468ef85017e97d46c55586edd0..66c4e7136b30c2343edd525a4e1793455e16b522 100644 --- a/p2p/net/conn/interface.go +++ b/p2p/net/conn/interface.go @@ -10,7 +10,7 @@ import ( transport "github.com/ipfs/go-libp2p/p2p/net/transport" peer "github.com/ipfs/go-libp2p/p2p/peer" - ma "github.com/jbenet/go-multiaddr" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" ) type PeerConn interface { diff --git a/p2p/net/conn/listen.go b/p2p/net/conn/listen.go index fcddc86057dbdf0524706262df9992e4a52195c6..60100d36c6ef688f5cd9046ccd6ac4e72bace1da 100644 --- a/p2p/net/conn/listen.go +++ b/p2p/net/conn/listen.go @@ -5,7 +5,7 @@ import ( "io" "net" - ma "github.com/jbenet/go-multiaddr" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" tec "github.com/jbenet/go-temp-err-catcher" "github.com/jbenet/goprocess" goprocessctx "github.com/jbenet/goprocess/context" diff --git a/p2p/net/conn/secure_conn.go b/p2p/net/conn/secure_conn.go index 1f27c909801930c2e92cf64880ebabe4d480d709..e13ea8a1e2f84c1735d6c7f231c810a46844642f 100644 --- a/p2p/net/conn/secure_conn.go +++ b/p2p/net/conn/secure_conn.go @@ -5,7 +5,7 @@ import ( "net" "time" - ma "github.com/jbenet/go-multiaddr" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" context "golang.org/x/net/context" ic "github.com/ipfs/go-libp2p/p2p/crypto" diff --git a/p2p/net/filter/filter.go b/p2p/net/filter/filter.go index 58154e214ab50190d49aeead1fd9fbc8b5385e53..f576bfc69023b7955c54302e98f7f586e10e6d40 100644 --- a/p2p/net/filter/filter.go +++ b/p2p/net/filter/filter.go @@ -5,8 +5,8 @@ import ( "strings" "sync" - ma "github.com/jbenet/go-multiaddr" - manet "github.com/jbenet/go-multiaddr-net" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" + manet "QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net" ) type Filters struct { diff --git a/p2p/net/interface.go b/p2p/net/interface.go index d0bd7fd2143056ce48fe1583f99fb40bb0876b2b..75fd196dedf6207137005107faaba1448f32d0e1 100644 --- a/p2p/net/interface.go +++ b/p2p/net/interface.go @@ -6,7 +6,7 @@ import ( conn "github.com/ipfs/go-libp2p/p2p/net/conn" peer "github.com/ipfs/go-libp2p/p2p/peer" - ma "github.com/jbenet/go-multiaddr" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" "github.com/jbenet/goprocess" context "golang.org/x/net/context" ) diff --git a/p2p/net/mock/interface.go b/p2p/net/mock/interface.go index a7fe45e70c0df2037c5ad9a8f46c6649ac1a52dc..3d197978710bb2cc97882f682b82943c708b3d81 100644 --- a/p2p/net/mock/interface.go +++ b/p2p/net/mock/interface.go @@ -14,7 +14,7 @@ import ( "io" "time" - ma "github.com/jbenet/go-multiaddr" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" ) type Mocknet interface { diff --git a/p2p/net/mock/mock_conn.go b/p2p/net/mock/mock_conn.go index 84ea48fc7be95e1c6bf4c9caf20e5bf85b2349e2..0f5ecd5c12b1aac8940db553eb43330ded1bbdf2 100644 --- a/p2p/net/mock/mock_conn.go +++ b/p2p/net/mock/mock_conn.go @@ -8,7 +8,7 @@ import ( inet "github.com/ipfs/go-libp2p/p2p/net" peer "github.com/ipfs/go-libp2p/p2p/peer" - ma "github.com/jbenet/go-multiaddr" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" process "github.com/jbenet/goprocess" ) diff --git a/p2p/net/mock/mock_net.go b/p2p/net/mock/mock_net.go index 8b2623e9ff0a730b1c87adc3313ee4005acb918e..ce4adcab052acbc8429f89e442bbc2e8dac5f9bb 100644 --- a/p2p/net/mock/mock_net.go +++ b/p2p/net/mock/mock_net.go @@ -13,7 +13,7 @@ import ( p2putil "github.com/ipfs/go-libp2p/p2p/test/util" testutil "util/testutil" - ma "github.com/jbenet/go-multiaddr" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" "github.com/jbenet/goprocess" goprocessctx "github.com/jbenet/goprocess/context" context "golang.org/x/net/context" diff --git a/p2p/net/mock/mock_notif_test.go b/p2p/net/mock/mock_notif_test.go index e80cda55c7c55b2234a282da15eed77208a9c65b..4874b1d13522e8b4b42199e7a22b6ee9fcc1bb4c 100644 --- a/p2p/net/mock/mock_notif_test.go +++ b/p2p/net/mock/mock_notif_test.go @@ -4,10 +4,10 @@ import ( "testing" "time" - ma "github.com/jbenet/go-multiaddr" - context "golang.org/x/net/context" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" inet "github.com/ipfs/go-libp2p/p2p/net" peer "github.com/ipfs/go-libp2p/p2p/peer" + context "golang.org/x/net/context" ) func TestNotifications(t *testing.T) { diff --git a/p2p/net/mock/mock_peernet.go b/p2p/net/mock/mock_peernet.go index 45f9256a16a9dbd95081757e416f0daeb1cab860..64b4a7b517fea5603bfc73caae757d8546ff6bcc 100644 --- a/p2p/net/mock/mock_peernet.go +++ b/p2p/net/mock/mock_peernet.go @@ -8,7 +8,7 @@ import ( inet "github.com/ipfs/go-libp2p/p2p/net" peer "github.com/ipfs/go-libp2p/p2p/peer" - ma "github.com/jbenet/go-multiaddr" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" "github.com/jbenet/goprocess" goprocessctx "github.com/jbenet/goprocess/context" context "golang.org/x/net/context" diff --git a/p2p/net/swarm/addr/addr.go b/p2p/net/swarm/addr/addr.go index cec777a25eeefab6697f40a8328ae91907e3f94c..cdb7058590db15b85c10a2210828b50ba2290d6d 100644 --- a/p2p/net/swarm/addr/addr.go +++ b/p2p/net/swarm/addr/addr.go @@ -5,8 +5,8 @@ import ( logging "QmWRypnfEwrgH4k93KEHN5hng7VjKYkWmzDYRuTZeh2Mgh/go-log" - ma "github.com/jbenet/go-multiaddr" - manet "github.com/jbenet/go-multiaddr-net" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" + manet "QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net" context "golang.org/x/net/context" ) diff --git a/p2p/net/swarm/addr/addr_test.go b/p2p/net/swarm/addr/addr_test.go index 49eec13511dd4ef99ee4db9d0eb7929f98bfff2e..2015b974cda88d8ac3eea90a0d9313c789471c31 100644 --- a/p2p/net/swarm/addr/addr_test.go +++ b/p2p/net/swarm/addr/addr_test.go @@ -3,8 +3,8 @@ package addrutil import ( "testing" - ma "github.com/jbenet/go-multiaddr" - manet "github.com/jbenet/go-multiaddr-net" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" + manet "QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net" ) func newMultiaddr(t *testing.T, s string) ma.Multiaddr { diff --git a/p2p/net/swarm/dial_test.go b/p2p/net/swarm/dial_test.go index f121f97f05126faf867c4172c2d117f9f4906a4e..77f827c333c592063c83c0fd7fa8756b8606a71a 100644 --- a/p2p/net/swarm/dial_test.go +++ b/p2p/net/swarm/dial_test.go @@ -13,8 +13,8 @@ import ( testutil "util/testutil" ci "util/testutil/ci" - ma "github.com/jbenet/go-multiaddr" - manet "github.com/jbenet/go-multiaddr-net" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" + manet "QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net" context "golang.org/x/net/context" ) diff --git a/p2p/net/swarm/peers_test.go b/p2p/net/swarm/peers_test.go index b107fbfe839b1ca47fcb8ebbe9d021d121402caf..cc8e14328f33843e680e060e149b75ded8945e14 100644 --- a/p2p/net/swarm/peers_test.go +++ b/p2p/net/swarm/peers_test.go @@ -5,7 +5,7 @@ import ( peer "github.com/ipfs/go-libp2p/p2p/peer" - ma "github.com/jbenet/go-multiaddr" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" context "golang.org/x/net/context" ) diff --git a/p2p/net/swarm/simul_test.go b/p2p/net/swarm/simul_test.go index 63e07ff8ac7e0eade7e2fb0dff33a48338f06242..c046ac2e4540d71560e76877d591a01f95143775 100644 --- a/p2p/net/swarm/simul_test.go +++ b/p2p/net/swarm/simul_test.go @@ -9,7 +9,7 @@ import ( peer "github.com/ipfs/go-libp2p/p2p/peer" ci "util/testutil/ci" - ma "github.com/jbenet/go-multiaddr" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" context "golang.org/x/net/context" ) diff --git a/p2p/net/swarm/swarm.go b/p2p/net/swarm/swarm.go index 245b7204f7cc16039f7d90bcf004a4d8062e5c40..d09b62ad502d873e3c221232817c107ae094cb2e 100644 --- a/p2p/net/swarm/swarm.go +++ b/p2p/net/swarm/swarm.go @@ -16,14 +16,14 @@ import ( transport "github.com/ipfs/go-libp2p/p2p/net/transport" peer "github.com/ipfs/go-libp2p/p2p/peer" - ma "github.com/jbenet/go-multiaddr" + mafilter "QmVdADza4QFVAR9xqAxRQjt9vTZJ6UrVLgBstKua1Xg7he/multiaddr-filter" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" ps "github.com/jbenet/go-peerstream" pst "github.com/jbenet/go-stream-muxer" psmss "github.com/jbenet/go-stream-muxer/multistream" "github.com/jbenet/goprocess" goprocessctx "github.com/jbenet/goprocess/context" prom "github.com/prometheus/client_golang/prometheus" - mafilter "github.com/whyrusleeping/multiaddr-filter" context "golang.org/x/net/context" logging "QmWRypnfEwrgH4k93KEHN5hng7VjKYkWmzDYRuTZeh2Mgh/go-log" diff --git a/p2p/net/swarm/swarm_addr.go b/p2p/net/swarm/swarm_addr.go index 039683bfb9cb77000dc3295778446c1218fd836a..87ee37bf17729ec20a5038639e44e41cdcf88c62 100644 --- a/p2p/net/swarm/swarm_addr.go +++ b/p2p/net/swarm/swarm_addr.go @@ -4,7 +4,7 @@ import ( conn "github.com/ipfs/go-libp2p/p2p/net/conn" addrutil "github.com/ipfs/go-libp2p/p2p/net/swarm/addr" - ma "github.com/jbenet/go-multiaddr" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" ) // ListenAddresses returns a list of addresses at which this swarm listens. diff --git a/p2p/net/swarm/swarm_addr_test.go b/p2p/net/swarm/swarm_addr_test.go index b1f167ae49a441ddbb82625d7ceea12b4dbf4c10..78685a4d382d4d4abb0fc351ea2c4a7b24e493b7 100644 --- a/p2p/net/swarm/swarm_addr_test.go +++ b/p2p/net/swarm/swarm_addr_test.go @@ -8,7 +8,7 @@ import ( peer "github.com/ipfs/go-libp2p/p2p/peer" testutil "util/testutil" - ma "github.com/jbenet/go-multiaddr" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" context "golang.org/x/net/context" ) diff --git a/p2p/net/swarm/swarm_conn.go b/p2p/net/swarm/swarm_conn.go index 840a9b465c111ae6ea3c8936ceba76617cf13e4a..c97a47dfcba775e6e0543fe0c9180a7ba036fbff 100644 --- a/p2p/net/swarm/swarm_conn.go +++ b/p2p/net/swarm/swarm_conn.go @@ -8,7 +8,7 @@ import ( conn "github.com/ipfs/go-libp2p/p2p/net/conn" peer "github.com/ipfs/go-libp2p/p2p/peer" - ma "github.com/jbenet/go-multiaddr" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" ps "github.com/jbenet/go-peerstream" context "golang.org/x/net/context" ) diff --git a/p2p/net/swarm/swarm_dial.go b/p2p/net/swarm/swarm_dial.go index 4790eb073826638f85066132f40db80d4ed4431c..47caa69d65712114812c25828aee8c33f62d5f9b 100644 --- a/p2p/net/swarm/swarm_dial.go +++ b/p2p/net/swarm/swarm_dial.go @@ -8,13 +8,13 @@ import ( "sync" "time" - "github.com/jbenet/go-multiaddr-net" + "QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net" conn "github.com/ipfs/go-libp2p/p2p/net/conn" addrutil "github.com/ipfs/go-libp2p/p2p/net/swarm/addr" peer "github.com/ipfs/go-libp2p/p2p/peer" lgbl "util/eventlog/loggables" - ma "github.com/jbenet/go-multiaddr" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" context "golang.org/x/net/context" ) diff --git a/p2p/net/swarm/swarm_listen.go b/p2p/net/swarm/swarm_listen.go index f3da2eeea74369c26ed11f8426a5e195d7df2999..394d5c2179f56e1d31cf933229ede8e4478e74b5 100644 --- a/p2p/net/swarm/swarm_listen.go +++ b/p2p/net/swarm/swarm_listen.go @@ -9,7 +9,7 @@ import ( transport "github.com/ipfs/go-libp2p/p2p/net/transport" lgbl "util/eventlog/loggables" - ma "github.com/jbenet/go-multiaddr" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" ps "github.com/jbenet/go-peerstream" context "golang.org/x/net/context" ) diff --git a/p2p/net/swarm/swarm_net.go b/p2p/net/swarm/swarm_net.go index 91c4208370af3008766fb39a315344e6db6b53f7..3c5e69225bd8857731f23123f9f54f0d49f3e9a8 100644 --- a/p2p/net/swarm/swarm_net.go +++ b/p2p/net/swarm/swarm_net.go @@ -8,7 +8,7 @@ import ( metrics "github.com/ipfs/go-libp2p/p2p/metrics" inet "github.com/ipfs/go-libp2p/p2p/net" - ma "github.com/jbenet/go-multiaddr" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" "github.com/jbenet/goprocess" context "golang.org/x/net/context" ) diff --git a/p2p/net/swarm/swarm_notif_test.go b/p2p/net/swarm/swarm_notif_test.go index 0d976e81d0c16aefd5e2264e83226c93537b602d..3d2ef86d7b2a47172853ba6e02a9602c697040b5 100644 --- a/p2p/net/swarm/swarm_notif_test.go +++ b/p2p/net/swarm/swarm_notif_test.go @@ -4,7 +4,7 @@ import ( "testing" "time" - ma "github.com/jbenet/go-multiaddr" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" context "golang.org/x/net/context" inet "github.com/ipfs/go-libp2p/p2p/net" diff --git a/p2p/net/swarm/swarm_test.go b/p2p/net/swarm/swarm_test.go index 2c98e5e854b1570a2d9924e537497954103c8790..c6e4a981d166d59c8868093e6715c16743f1989a 100644 --- a/p2p/net/swarm/swarm_test.go +++ b/p2p/net/swarm/swarm_test.go @@ -14,7 +14,7 @@ import ( peer "github.com/ipfs/go-libp2p/p2p/peer" testutil "util/testutil" - ma "github.com/jbenet/go-multiaddr" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" context "golang.org/x/net/context" ) diff --git a/p2p/net/transport/tcp.go b/p2p/net/transport/tcp.go index b16a86f06c7beca2a76dea5f3c9f6590192f125b..3671cbfeeedadf7ae0af939095556ab1f2df2fa2 100644 --- a/p2p/net/transport/tcp.go +++ b/p2p/net/transport/tcp.go @@ -6,8 +6,8 @@ import ( "sync" "time" - ma "github.com/jbenet/go-multiaddr" - manet "github.com/jbenet/go-multiaddr-net" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" + manet "QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net" reuseport "github.com/jbenet/go-reuseport" context "golang.org/x/net/context" lgbl "util/eventlog/loggables" diff --git a/p2p/net/transport/transport.go b/p2p/net/transport/transport.go index 80cf1be171a32fb34cdf2f0fd892815e8f36b9e9..939244fbd89394a84718908d638c7e131ff971ab 100644 --- a/p2p/net/transport/transport.go +++ b/p2p/net/transport/transport.go @@ -5,8 +5,8 @@ import ( "time" logging "QmWRypnfEwrgH4k93KEHN5hng7VjKYkWmzDYRuTZeh2Mgh/go-log" - ma "github.com/jbenet/go-multiaddr" - manet "github.com/jbenet/go-multiaddr-net" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" + manet "QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net" ) var log = logging.Logger("transport") diff --git a/p2p/peer/addr/addrsrcs.go b/p2p/peer/addr/addrsrcs.go index a172373d8dccaffe46efd234dd73b2df85b8f15c..f6ea1c1835595cb87f28f386aedfcbdffaf940a9 100644 --- a/p2p/peer/addr/addrsrcs.go +++ b/p2p/peer/addr/addrsrcs.go @@ -2,7 +2,7 @@ package addr import ( - ma "github.com/jbenet/go-multiaddr" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" ) // AddrSource is a source of addresses. It allows clients to retrieve diff --git a/p2p/peer/addr/addrsrcs_test.go b/p2p/peer/addr/addrsrcs_test.go index 46140641caae9923607132c4533beb577069aadc..cc7fdd54b3c4a4539a813bd224a5468433630258 100644 --- a/p2p/peer/addr/addrsrcs_test.go +++ b/p2p/peer/addr/addrsrcs_test.go @@ -4,7 +4,7 @@ import ( "fmt" "testing" - ma "github.com/jbenet/go-multiaddr" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" ) func newAddrOrFatal(t *testing.T, s string) ma.Multiaddr { diff --git a/p2p/peer/addr_manager.go b/p2p/peer/addr_manager.go index 87b8206eee67cc23106d16785a2c3be4ccd1ba72..1775069f7e42084f959cae34054438967a216e03 100644 --- a/p2p/peer/addr_manager.go +++ b/p2p/peer/addr_manager.go @@ -4,7 +4,7 @@ import ( "sync" "time" - ma "github.com/jbenet/go-multiaddr" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" ) const ( diff --git a/p2p/peer/addr_manager_test.go b/p2p/peer/addr_manager_test.go index 3e19530539f5b838b2d199e7188061be88869e20..d22198284d672486dd47af313d824586964132a6 100644 --- a/p2p/peer/addr_manager_test.go +++ b/p2p/peer/addr_manager_test.go @@ -4,7 +4,7 @@ import ( "testing" "time" - ma "github.com/jbenet/go-multiaddr" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" ) func IDS(t *testing.T, ids string) ID { diff --git a/p2p/peer/peer.go b/p2p/peer/peer.go index 549b2093a61fa96e45803321959f7653dfcb5ffe..1b59a821aa4083144845c3551df66430e61a8200 100644 --- a/p2p/peer/peer.go +++ b/p2p/peer/peer.go @@ -7,9 +7,9 @@ import ( "fmt" "strings" - b58 "github.com/jbenet/go-base58" - ma "github.com/jbenet/go-multiaddr" - mh "github.com/jbenet/go-multihash" + b58 "QmNsoHoCVhgXcv1Yg45jtkMgimxorTAN36fV9AQMFXHHAQ/go-base58" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" + mh "QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash" logging "QmWRypnfEwrgH4k93KEHN5hng7VjKYkWmzDYRuTZeh2Mgh/go-log" ic "github.com/ipfs/go-libp2p/p2p/crypto" diff --git a/p2p/peer/peer_test.go b/p2p/peer/peer_test.go index 1d4ca2595bb7e26a07d617a86738fb070787418f..502d8aba0678962ce3455bc80293f51f6ab0f426 100644 --- a/p2p/peer/peer_test.go +++ b/p2p/peer/peer_test.go @@ -11,7 +11,7 @@ import ( u "util" tu "util/testutil" - b58 "github.com/jbenet/go-base58" + b58 "QmNsoHoCVhgXcv1Yg45jtkMgimxorTAN36fV9AQMFXHHAQ/go-base58" ) var gen1 keyset // generated diff --git a/p2p/peer/peerstore.go b/p2p/peer/peerstore.go index 9f3a98d25dbc0d2f1b3e45acff223cd0fcd7595c..8c2ae05a890158abbf02606926a54b40e1f1c272 100644 --- a/p2p/peer/peerstore.go +++ b/p2p/peer/peerstore.go @@ -7,9 +7,9 @@ import ( ic "github.com/ipfs/go-libp2p/p2p/crypto" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" ds "github.com/jbenet/go-datastore" dssync "github.com/jbenet/go-datastore/sync" - ma "github.com/jbenet/go-multiaddr" ) const ( diff --git a/p2p/peer/queue/queue_test.go b/p2p/peer/queue/queue_test.go index d85f84b7c209597057a4b15b5cf09918da80c665..9d8a42718a1a6d1b36afe9de3855142b3d637b45 100644 --- a/p2p/peer/queue/queue_test.go +++ b/p2p/peer/queue/queue_test.go @@ -7,7 +7,6 @@ import ( "time" peer "github.com/ipfs/go-libp2p/p2p/peer" - key "github.com/whyrusleeping/go-key" u "util" context "golang.org/x/net/context" @@ -28,7 +27,7 @@ func TestQueue(t *testing.T) { // [78 135 26 216 178 181 224 181 234 117 2 248 152 115 255 103 244 34 4 152 193 88 9 225 8 127 216 158 226 8 236 246] // [125 135 124 6 226 160 101 94 192 57 39 12 18 79 121 140 190 154 147 55 44 83 101 151 63 255 94 179 51 203 241 51] - pq := NewXORDistancePQ(key.Key("11140beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a31")) + pq := NewXORDistancePQ("11140beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a31") pq.Enqueue(p3) pq.Enqueue(p1) pq.Enqueue(p2) @@ -82,7 +81,7 @@ func TestSyncQueue(t *testing.T) { } ctx := context.Background() - pq := NewXORDistancePQ(key.Key("11140beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a31")) + pq := NewXORDistancePQ("11140beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a31") cq := NewChanQueue(ctx, pq) wg := sync.WaitGroup{} diff --git a/p2p/protocol/identify/id.go b/p2p/protocol/identify/id.go index c6c44fa06d888e82a79a9bb6626a2dc45a9bd976..c4a3ba4c4ae2b9dd06d6cae19b81e6338ac961cd 100644 --- a/p2p/protocol/identify/id.go +++ b/p2p/protocol/identify/id.go @@ -4,9 +4,9 @@ import ( "strings" "sync" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" semver "github.com/coreos/go-semver/semver" ggio "github.com/gogo/protobuf/io" - ma "github.com/jbenet/go-multiaddr" msmux "github.com/whyrusleeping/go-multistream" context "golang.org/x/net/context" diff --git a/p2p/protocol/identify/id_test.go b/p2p/protocol/identify/id_test.go index 1057786d41f6f7bda9e1ad7c050daafed4dc3477..47f7956f8647b0c9fe45099e6abc8d5942e6ee0b 100644 --- a/p2p/protocol/identify/id_test.go +++ b/p2p/protocol/identify/id_test.go @@ -9,7 +9,7 @@ import ( identify "github.com/ipfs/go-libp2p/p2p/protocol/identify" testutil "github.com/ipfs/go-libp2p/p2p/test/util" - ma "github.com/jbenet/go-multiaddr" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" context "golang.org/x/net/context" ) diff --git a/p2p/protocol/identify/obsaddr.go b/p2p/protocol/identify/obsaddr.go index 98c29b2773cbbb3cf117a35cd48ac3ddc2459b00..042eaa8e25aad61eea9502bfb9ef980671877c6e 100644 --- a/p2p/protocol/identify/obsaddr.go +++ b/p2p/protocol/identify/obsaddr.go @@ -6,7 +6,7 @@ import ( peer "github.com/ipfs/go-libp2p/p2p/peer" - ma "github.com/jbenet/go-multiaddr" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" ) // ObservedAddr is an entry for an address reported by our peers. diff --git a/p2p/protocol/identify/obsaddr_test.go b/p2p/protocol/identify/obsaddr_test.go index 81413c4f091f703f676aa437b2fedf66ab1da9d3..6db84dc1e881cc53373b54bc61f0964e807cf1e4 100644 --- a/p2p/protocol/identify/obsaddr_test.go +++ b/p2p/protocol/identify/obsaddr_test.go @@ -4,7 +4,7 @@ import ( "testing" "time" - ma "github.com/jbenet/go-multiaddr" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" ) // TestObsAddrSet diff --git a/p2p/protocol/relay/relay.go b/p2p/protocol/relay/relay.go index 9a266216fee5e50e91978b67850777feb99d1814..fa10901e6ffcbd4e4c3472dd59435029d31a1579 100644 --- a/p2p/protocol/relay/relay.go +++ b/p2p/protocol/relay/relay.go @@ -4,13 +4,13 @@ import ( "fmt" "io" - mh "github.com/jbenet/go-multihash" + mh "QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash" + logging "QmWRypnfEwrgH4k93KEHN5hng7VjKYkWmzDYRuTZeh2Mgh/go-log" host "github.com/ipfs/go-libp2p/p2p/host" inet "github.com/ipfs/go-libp2p/p2p/net" peer "github.com/ipfs/go-libp2p/p2p/peer" protocol "github.com/ipfs/go-libp2p/p2p/protocol" - logging "QmWRypnfEwrgH4k93KEHN5hng7VjKYkWmzDYRuTZeh2Mgh/go-log" ) var log = logging.Logger("github.com/ipfs/go-libp2p/p2p/protocol/relay") diff --git a/p2p/test/util/key.go b/p2p/test/util/key.go index 9a6538904a72d48b2ba5452d40fbd1e523c42b2b..b8aa835097b6cb626c96c2e7bbb9abdf20234509 100644 --- a/p2p/test/util/key.go +++ b/p2p/test/util/key.go @@ -5,14 +5,14 @@ import ( "io" "testing" + logging "QmWRypnfEwrgH4k93KEHN5hng7VjKYkWmzDYRuTZeh2Mgh/go-log" u "util" testutil "util/testutil" - logging "QmWRypnfEwrgH4k93KEHN5hng7VjKYkWmzDYRuTZeh2Mgh/go-log" ic "github.com/ipfs/go-libp2p/p2p/crypto" peer "github.com/ipfs/go-libp2p/p2p/peer" - ma "github.com/jbenet/go-multiaddr" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" ) var log = logging.Logger("boguskey") diff --git a/p2p/test/util/util.go b/p2p/test/util/util.go index efd3eacac9d71602e2c8ba0234d1c51dc9cc3049..760cea6f52b57bdd0e153310394f4ae7d7866828 100644 --- a/p2p/test/util/util.go +++ b/p2p/test/util/util.go @@ -10,7 +10,7 @@ import ( peer "github.com/ipfs/go-libp2p/p2p/peer" tu "util/testutil" - ma "github.com/jbenet/go-multiaddr" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" context "golang.org/x/net/context" ) diff --git a/package.json b/package.json index 5942940a85eb88607eab4a0a231c53ca6a59fa1b..7b61e8e9b20c43d140748886239c32d19aa39f62 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,16 @@ "name": "go-keyspace", "hash": "Qma4vHVBYKDiKS5VpvtLNJHHDbL7S6VRsvxxmBnBFfKP3k", "version": "1.0.0" + }, + { + "name": "go-multiaddr-net", + "hash": "QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr", + "version": "1.0.0" + }, + { + "name": "multiaddr-filter", + "hash": "QmVdADza4QFVAR9xqAxRQjt9vTZJ6UrVLgBstKua1Xg7he", + "version": "1.0.0" } ], "language": "go" diff --git a/vendor/QmNsoHoCVhgXcv1Yg45jtkMgimxorTAN36fV9AQMFXHHAQ/go-base58/LICENSE b/vendor/QmNsoHoCVhgXcv1Yg45jtkMgimxorTAN36fV9AQMFXHHAQ/go-base58/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..0d760cbb4d594f6ff48d7b2fafb6244d72394756 --- /dev/null +++ b/vendor/QmNsoHoCVhgXcv1Yg45jtkMgimxorTAN36fV9AQMFXHHAQ/go-base58/LICENSE @@ -0,0 +1,13 @@ +Copyright (c) 2013 Conformal Systems LLC. + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. \ No newline at end of file diff --git a/vendor/QmNsoHoCVhgXcv1Yg45jtkMgimxorTAN36fV9AQMFXHHAQ/go-base58/README.md b/vendor/QmNsoHoCVhgXcv1Yg45jtkMgimxorTAN36fV9AQMFXHHAQ/go-base58/README.md new file mode 100644 index 0000000000000000000000000000000000000000..ece2433411cf5dbb8bb9b6d9e41f2bfb9744ab6c --- /dev/null +++ b/vendor/QmNsoHoCVhgXcv1Yg45jtkMgimxorTAN36fV9AQMFXHHAQ/go-base58/README.md @@ -0,0 +1,66 @@ +# go-base58 + +I extracted this package from https://github.com/conformal/btcutil to provide a simple base58 package that +- defaults to base58-check (btc) +- and allows using different alphabets. + +## Usage + +```go +package main + +import ( + "fmt" + b58 "github.com/jbenet/go-base58" +) + +func main() { + buf := []byte{255, 254, 253, 252} + fmt.Printf("buffer: %v\n", buf) + + str := b58.Encode(buf) + fmt.Printf("encoded: %s\n", str) + + buf2 := b58.Decode(str) + fmt.Printf("decoded: %v\n", buf2) +} +``` + +### Another alphabet + +```go +package main + +import ( + "fmt" + b58 "github.com/jbenet/go-base58" +) + +const BogusAlphabet = "ZYXWVUTSRQPNMLKJHGFEDCBAzyxwvutsrqponmkjihgfedcba987654321" + + +func encdec(alphabet string) { + fmt.Printf("using: %s\n", alphabet) + + buf := []byte{255, 254, 253, 252} + fmt.Printf("buffer: %v\n", buf) + + str := b58.EncodeAlphabet(buf, alphabet) + fmt.Printf("encoded: %s\n", str) + + buf2 := b58.DecodeAlphabet(str, alphabet) + fmt.Printf("decoded: %v\n\n", buf2) +} + + +func main() { + encdec(b58.BTCAlphabet) + encdec(b58.FlickrAlphabet) + encdec(BogusAlphabet) +} +``` + + +## License + +Package base58 (and the original btcutil) are licensed under the ISC License. diff --git a/vendor/QmNsoHoCVhgXcv1Yg45jtkMgimxorTAN36fV9AQMFXHHAQ/go-base58/base58.go b/vendor/QmNsoHoCVhgXcv1Yg45jtkMgimxorTAN36fV9AQMFXHHAQ/go-base58/base58.go new file mode 100644 index 0000000000000000000000000000000000000000..ad91df54a1552ec29aff540ea480a35727e90f0e --- /dev/null +++ b/vendor/QmNsoHoCVhgXcv1Yg45jtkMgimxorTAN36fV9AQMFXHHAQ/go-base58/base58.go @@ -0,0 +1,90 @@ +// Copyright (c) 2013-2014 Conformal Systems LLC. +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. +// Modified by Juan Benet (juan@benet.ai) + +package base58 + +import ( + "math/big" + "strings" +) + +// alphabet is the modified base58 alphabet used by Bitcoin. +const BTCAlphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" +const FlickrAlphabet = "123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ" + +var bigRadix = big.NewInt(58) +var bigZero = big.NewInt(0) + +// Decode decodes a modified base58 string to a byte slice, using BTCAlphabet +func Decode(b string) []byte { + return DecodeAlphabet(b, BTCAlphabet) +} + +// Encode encodes a byte slice to a modified base58 string, using BTCAlphabet +func Encode(b []byte) string { + return EncodeAlphabet(b, BTCAlphabet) +} + +// DecodeAlphabet decodes a modified base58 string to a byte slice, using alphabet. +func DecodeAlphabet(b, alphabet string) []byte { + answer := big.NewInt(0) + j := big.NewInt(1) + + for i := len(b) - 1; i >= 0; i-- { + tmp := strings.IndexAny(alphabet, string(b[i])) + if tmp == -1 { + return []byte("") + } + idx := big.NewInt(int64(tmp)) + tmp1 := big.NewInt(0) + tmp1.Mul(j, idx) + + answer.Add(answer, tmp1) + j.Mul(j, bigRadix) + } + + tmpval := answer.Bytes() + + var numZeros int + for numZeros = 0; numZeros < len(b); numZeros++ { + if b[numZeros] != alphabet[0] { + break + } + } + flen := numZeros + len(tmpval) + val := make([]byte, flen, flen) + copy(val[numZeros:], tmpval) + + return val +} + +// Encode encodes a byte slice to a modified base58 string, using alphabet +func EncodeAlphabet(b []byte, alphabet string) string { + x := new(big.Int) + x.SetBytes(b) + + answer := make([]byte, 0, len(b)*136/100) + for x.Cmp(bigZero) > 0 { + mod := new(big.Int) + x.DivMod(x, bigRadix, mod) + answer = append(answer, alphabet[mod.Int64()]) + } + + // leading zero bytes + for _, i := range b { + if i != 0 { + break + } + answer = append(answer, alphabet[0]) + } + + // reverse + alen := len(answer) + for i := 0; i < alen/2; i++ { + answer[i], answer[alen-1-i] = answer[alen-1-i], answer[i] + } + + return string(answer) +} diff --git a/vendor/QmNsoHoCVhgXcv1Yg45jtkMgimxorTAN36fV9AQMFXHHAQ/go-base58/base58_test.go b/vendor/QmNsoHoCVhgXcv1Yg45jtkMgimxorTAN36fV9AQMFXHHAQ/go-base58/base58_test.go new file mode 100644 index 0000000000000000000000000000000000000000..3e945b29dca57c77c9adda9236df20551e0989bb --- /dev/null +++ b/vendor/QmNsoHoCVhgXcv1Yg45jtkMgimxorTAN36fV9AQMFXHHAQ/go-base58/base58_test.go @@ -0,0 +1,130 @@ +// Copyright (c) 2013-2014 Conformal Systems LLC. +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package base58 + +import ( + "bytes" + "encoding/hex" + "testing" +) + +var stringTests = []struct { + in string + out string +}{ + {"", ""}, + {" ", "Z"}, + {"-", "n"}, + {"0", "q"}, + {"1", "r"}, + {"-1", "4SU"}, + {"11", "4k8"}, + {"abc", "ZiCa"}, + {"1234598760", "3mJr7AoUXx2Wqd"}, + {"abcdefghijklmnopqrstuvwxyz", "3yxU3u1igY8WkgtjK92fbJQCd4BZiiT1v25f"}, + {"00000000000000000000000000000000000000000000000000000000000000", "3sN2THZeE9Eh9eYrwkvZqNstbHGvrxSAM7gXUXvyFQP8XvQLUqNCS27icwUeDT7ckHm4FUHM2mTVh1vbLmk7y"}, +} + +var invalidStringTests = []struct { + in string + out string +}{ + {"0", ""}, + {"O", ""}, + {"I", ""}, + {"l", ""}, + {"3mJr0", ""}, + {"O3yxU", ""}, + {"3sNI", ""}, + {"4kl8", ""}, + {"0OIl", ""}, + {"!@#$%^&*()-_=+~`", ""}, +} + +var hexTests = []struct { + in string + out string +}{ + {"61", "2g"}, + {"626262", "a3gV"}, + {"636363", "aPEr"}, + {"73696d706c792061206c6f6e6720737472696e67", "2cFupjhnEsSn59qHXstmK2ffpLv2"}, + {"00eb15231dfceb60925886b67d065299925915aeb172c06647", "1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L"}, + {"516b6fcd0f", "ABnLTmg"}, + {"bf4f89001e670274dd", "3SEo3LWLoPntC"}, + {"572e4794", "3EFU7m"}, + {"ecac89cad93923c02321", "EJDM8drfXA6uyA"}, + {"10c8511e", "Rt5zm"}, + {"00000000000000000000", "1111111111"}, +} + +func TestBase58(t *testing.T) { + // Base58Encode tests + for x, test := range stringTests { + tmp := []byte(test.in) + if res := Encode(tmp); res != test.out { + t.Errorf("Base58Encode test #%d failed: got: %s want: %s", + x, res, test.out) + continue + } + } + + // Base58Decode tests + for x, test := range hexTests { + b, err := hex.DecodeString(test.in) + if err != nil { + t.Errorf("hex.DecodeString failed failed #%d: got: %s", x, test.in) + continue + } + if res := Decode(test.out); bytes.Equal(res, b) != true { + t.Errorf("Base58Decode test #%d failed: got: %q want: %q", + x, res, test.in) + continue + } + } + + // Base58Decode with invalid input + for x, test := range invalidStringTests { + if res := Decode(test.in); string(res) != test.out { + t.Errorf("Base58Decode invalidString test #%d failed: got: %q want: %q", + x, res, test.out) + continue + } + } +} + +func BenchmarkDecodeShort(b *testing.B) { + const in = "1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L" + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = Decode(in) + } +} + +func BenchmarkEncodeShort(b *testing.B) { + var in = []byte("00eb15231dfceb60925886b67d065299925915aeb172c06647") + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = Encode(in) + } +} + +func BenchmarkDecodeOneKilo(b *testing.B) { + const in = "3GimCffBLAHhXMCeNxX2nST6dBem9pbUi3KVKykW73LmewcFtMk9oh9eNPdNR2eSzNqp7Z3E21vrWUkGHzJ7w2yqDUDJ4LKo1w5D6aafZ4SUoNQyrSVxyVG3pwgoZkKXMZVixRyiPZVUpekrsTvZuUoW7mB6BQgDTXbDuMMSRoNR7yiUTKpgwTD61DLmhNZopNxfFjn4avpYPgzsTB94iWueq1yU3EoruWCUMvp6fc1CEbDrZY3pkx9oUbUaSMC37rruBKSSGHh1ZE3XK3kQXBCFraMmUQf8dagofMEg5aTnDiLAZjLyWJMdnQwW1FqKKztP8KAQS2JX8GCCfc68KB4VGf2CfEGXtaapnsNWFrHuWi7Wo5vqyuHd21zGm1u5rsiR6tKNCsFC4nzf3WUNxJNoZrDSdF9KERqhTWWmmcM4qdKRCtBWKTrs1DJD2oiK6BK9BgwoW2dfQdKuxojFyFvmxqPKDDAEZPPpJ51wHoFzBFMM1tUBBkN15cT2GpNwKzDcjHPKJAQ6FNRgppfQytzqpq76sSeZaWAB8hhULMJCQGU57ZUjvP7xYAQwtACBnYrjdxA91XwXFbq5AsQJwAmLw6euKVWNyv11BuHrejVmnNViWg5kuZBrtgL6NtzRWHtdxngHDMtuyky3brqGXaGQhUyXrkSpeknkkHL6NLThHH5NPnfFMVPwn2xf5UM5R51X2nTBzADSVcpi4cT7i44dT7o3yRKWtKfUzZiuNyTcSSrfH8KVdLap5ZKLmdPuXM65M2Z5wJVh3Uc4iv6iZKk44RKikM7zs1hqC4sBxRwLZjxhKvvMXDjDcYFkzyUkues4y7fjdCnVTxc4vTYUqcbY2k2WMssyj9SDseVc7dVrEvWCLQtYy79mJFoz1Hmsfk5ynE28ipznzQ3yTBugLHA6j6qW3S74eY4pJ6iynFEuXT4RqqkLGFcMh3goqS7CkphUMzP4wuJyGnzqa5tCno4U3dJ2jUL7Povg8voRqYAfiHyXC8zuhn225EdmRcSnu2pAuutQVV9hN3bkjfzAFUhUWKki8SwXtFSjy6NJyrYUiaze4p7ApsjHQBCgg2zAoBaGCwVN8991Jny31B5vPyYHy1oRSE4xTVZ7tTw9FyQ7w9p1NSEF4sziCxZHh5rFWZKAajc5c7KaMNDvHPNV6S62MTFGTyuKPQNbv9yHRGN4eH6SnZGW6snvEVdYCspWZ1U3Nbxo6vCmBK95UyYpcxHgg1CCGdU4s3edju2NDQkMifyPkJdkabzzHVDhJJbChAJc1ACQfNW74VXXwrBZmeZyA2R28MBctDyXuSuffiwueys2LVowLu9wiTHUox7KQjtHK2c9howk9czzx2mpnYzkVYH42CYsWa5514EM4CJEXPJSSbXSgJJ" + b.SetBytes(int64(len(in))) // 1024 + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = Decode(in) + } +} + +func BenchmarkEncodeOneKilo(b *testing.B) { + var in = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x00\x00\x04\xff\xfb\x63\xc9\x7e\x5f\x97\x68\xe5\x10\x08\xe5\xa5\x9a\x7c\x24\x75\x35\xbe\xaf\x37\x0b\xc3\xf4\x18\x62\x4a\xb7\x18\xd0\x10\x0b\x6b\x62\xe1\x36\x0f\x62\xa6\xeb\x78\xa5\xf3\x33\x52\xbc\xdf\x04\xcb\x37\xcf\x3d\x97\x5c\xb8\x75\x09\x1f\x18\x9f\xfc\xa9\xda\x1e\x59\x77\x09\x9c\x5d\xb6\xf2\x9e\x45\xb7\x5e\x5d\x11\xf1\x20\x14\x85\xf8\x54\x87\x8c\x1e\x2c\x2e\x15\x57\x89\xe7\x5d\x49\xb6\xae\x24\x3a\x20\x50\x0e\xa7\x5b\x10\xbf\x0a\xb4\x01\x42\xed\xce\x2d\x45\x21\xb6\xe8\x64\x73\x4e\x7e\x0a\x36\x1d\x57\x0a\x5e\x1c\x21\xc2\xb8\xe7\x89\x82\xe4\x04\x7e\x50\xff\xda\x4f\xfe\x11\x95\xfb\x35\xf9\x6d\x32\xce\xef\x8f\x3d\x1b\xdb\x38\xfa\xcd\x26\x36\x12\x93\xa0\x96\xea\x42\xbe\xd6\x85\x86\xc1\xc1\xe2\x55\x41\xd1\x7f\x8d\x0e\x00\x81\x58\xb4\x10\xbb\x64\x92\x05\x07\xa9\xd5\xd9\x40\x28\x8b\x9b\x4c\x8d\x8e\x4e\x69\xf9\xc9\x35\xea\xda\x2f\x61\x87\x35\x2d\x6b\x25\x32\xf0\x7e\x89\x1a\xcb\xc0\xea\x66\x88\x99\x39\xe0\x3b\x24\x3b\x05\x74\xd3\x72\xf6\x48\x15\xdc\x02\x0a\xbf\xc8\x49\x42\x10\x22\xeb\xe9\x44\x71\x55\xaf\x67\x67\xe6\x2a\x40\x31\x81\xb9\x6f\x65\x86\x0f\x0f\x9d\x58\x4c\x51\xc1\x2e\x4e\x60\x7e\xe8\x93\x39\x90\xda\xe5\xbe\xec\xe4\xdd\xbc\x1d\xba\x40\xa6\x85\xd9\xb2\xec\xb4\x26\x74\xee\xc1\xec\xe3\x40\xb9\x49\xa3\xe1\x26\x76\x8a\xeb\x95\xc8\x72\xb0\x85\x36\x19\x3f\x55\x06\x7b\xcd\x3e\xd0\xdf\x7e\x8d\x2a\xea\xa6\x24\xc6\xf6\xfb\xda\xe0\x45\xcf\x32\x0e\xbc\xf4\x41\x7d\x71\x3d\x86\xf9\xb4\xaf\x07\xa0\xd1\x34\x8a\x02\x28\x56\xd4\xcc\x36\x44\x98\x44\xcb\x9d\xc5\xfc\x45\x2d\xc4\x5c\xfe\xce\xaa\x44\xda\x66\x52\x2d\x32\x6e\x13\x32\xac\xaf\x13\x72\x87\x79\xd2\x92\x54\x9f\xc7\xb9\xf3\x21\xae\xdd\x69\x44\xe9\x46\x94\x1c\x62\x84\x03\xe0\xbf\x66\xfb\xe0\x79\xf9\x57\x9e\x22\x9e\x23\x2d\x2a\x73\xeb\x74\x38\xf0\xea\x5d\xb3\x8f\x87\x26\x3e\x3c\x54\x11\xb7\x98\xbd\x7f\x78\x64\xa3\xf1\x8f\xa9\x5e\x4f\x18\x3f\xa7\x1f\x3a\x29\x27\x27\xb7\x49\x40\x16\x18\x1f\xd3\xed\x86\x61\xbd\xc3\x4e\x4a\x53\x37\x78\x5c\x00\xd3\x50\x45\x1c\x55\xc0\x9b\xd7\x62\x29\x88\x2e\xa4\x0d\x6a\x15\x6c\x33\x3c\xe7\x31\xfa\xc1\xaf\xdf\x7a\x3e\x37\x3e\xe5\xbc\xfd\xfb\x9b\x72\x10\x35\x90\x25\x6e\x87\x0d\x74\x1c\xfd\xe3\x0b\xee\xf5\x92\x28\x8d\x22\x8a\x49\x7b\xcd\xbb\xd8\x24\x6b\x5e\x58\x40\xec\x1b\x6c\xed\x8e\xcb\x56\x62\xa6\xb4\x42\x3d\x7d\xa2\xef\x27\x27\x46\x50\xbc\x5e\x37\x9b\x27\x72\xf0\xea\xa7\xe7\x4d\xf4\xae\x7e\x95\x8f\x91\x2e\x58\xc4\x6a\x06\xda\x7a\x06\x5c\x8d\xfe\xef\xf5\xb3\x0f\xb4\x0a\x20\x53\xd8\x35\x80\x02\xca\x97\x81\xb6\x1c\x4b\x8f\xb7\xee\xd0\xc3\x88\x6c\x76\x3e\xb0\x28\xce\xa1\x9f\x76\x5f\xaa\xc3\x53\x44\x09\x70\xa3\x95\xd9\x8c\x54\xba\x8a\x9a\x6b\xce\xc3\x07\xdf\x13\x6d\xea\x0f\x51\x9c\xe2\x81\x87\xf6\x82\x7a\x70\xd8\xfa\xe2\xa8\x32\xc1\x5e\x53\xc2\x85\xe9\x61\x8a\x17\x82\x12\xab\x92\x79\x2b\xed\x07\xca\x1e\x93\x23\x9c\x4b\xd2\x89\x86\xac\x55\xf9\x50\x23\x8f\x9e\xd3\xab\x22\x57\x91\x5a\x0b\x48\xd7\xa2\xb8\x06\xbb\x74\xae\xe9\xca\x06\x41\x8d\x6a\x00\x42\xc4\x40\xa9\xfe\xae\x88\x42\xc2\x83\xe0\x8a\xd8\x5c\xbb\x5a\xb5\x9c\x1d\xa5\xbe\x67\x50\xb1\x4e\xec\x96\x65\xaa\x87\x5b\xb0\x76\x88\xe3\x1b\xcb\x38\x21\x02\x8e\xc9\xe7\xf5\xc7\xe1\x1d\xe8\xeb\x54\x0e\x0b\xea\xd1\x2e\xad\xbb\xec\x22\x21\xb3\x64\x36\x29\x34\x5e\x3a\x22\xe8\x03\x4b\x86\xb1\x67\x7d\x4f\x48\x6d\xfb\x4b\xde\xe6\x4c\xb0\xaf\x40\x66\xab\xe9\x1a\x4e\xae\x1a\x7e\x05\xc5\x67\x2a\x95\x6d\xc2\x61\x35\x20\xfe\x33\xc3\x2c\x7f\x9b\xbe\x9f\x9a\xd5\xf0\x63\x28\xa1\x94\xb1\x5c\xc1\x18\x6b\x5b\x33\xb4\x4d\xcf\xbe\xf7\xb2\x94\x58\xaa\xcf\xad\xc8\x75\x93\x1a\x08\xf4\xd2\xd9\xf6\x95\x03\x3b\xf3\x4e\xfb\x15\xe4\x28\xed\xd5\x79\xd9\xbf\xb7\x8f\xb2\x70\x16\x4c\x2d\x65\xf6\xec\x33\x1e\xaf\xea\x46\x69\xc6\x9a\x6b\xdd\xf3\x57\xe0\x1d\x28\xcd\xf8\x83\x3d\x94\x4c\x2f\x6e\xfd\x51\x3d\xa8\xff\xcb\x33\xad\x32\x42\x0e\xd3\x00\x0a\xe5\x71\x76\x3b\x83\xc9\x2a\x67\x50\xc3\xa5\xeb\x4d\x8d\x67\xd6\xd9\x1b\x9a\x5a\xbe\xdd\xc5\x15\x00\xcf\x97\x0f\x47\x44\x34\x1d\x4e\xb6\x6f\x91\x31\xf3\x45\x0f\x59\x48\x10\x23\x53\x40\x49\x83\xe6\xc8\xdf\x51\x6c\xa8\x9f\x3a\x43\x3d\xb9\xd4\xea\x30\x4d\xe0\xd2\xb8\x44\xf3\x91\x20\x79\xdb\x7b\xe6\x50\xf9\x0f\xfb\x4c\xac\x79\x93\xf6\xf8\x96\x0d\x55\x7c\x41\x9b\x1a\x86\xad\x4b\xd1\xf9\x5d\xed\x3a\x4f\xc9\x64\x72\xd4\x22\x53\x59\x2f\x01\x00\x00\xff\xff\xc6\xfd\xa0\x37\x00\x04\x00\x00") + b.SetBytes(int64(len(in))) // 1024 + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = Encode(in) + } +} diff --git a/vendor/QmNsoHoCVhgXcv1Yg45jtkMgimxorTAN36fV9AQMFXHHAQ/go-base58/doc.go b/vendor/QmNsoHoCVhgXcv1Yg45jtkMgimxorTAN36fV9AQMFXHHAQ/go-base58/doc.go new file mode 100644 index 0000000000000000000000000000000000000000..315c6107dcebe438778fe1e368d51d82d716d3f2 --- /dev/null +++ b/vendor/QmNsoHoCVhgXcv1Yg45jtkMgimxorTAN36fV9AQMFXHHAQ/go-base58/doc.go @@ -0,0 +1,20 @@ +// Copyright (c) 2013-2014 Conformal Systems LLC. +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +/* +Package base58 provides base58-check encoding. +The alphabet is modifyiable for + +Base58 Usage + +To decode a base58 string: + + rawData := base58.Base58Decode(encodedData) + +Similarly, to encode the same data: + + encodedData := base58.Base58Encode(rawData) + +*/ +package base58 diff --git a/vendor/QmNsoHoCVhgXcv1Yg45jtkMgimxorTAN36fV9AQMFXHHAQ/go-base58/package.json b/vendor/QmNsoHoCVhgXcv1Yg45jtkMgimxorTAN36fV9AQMFXHHAQ/go-base58/package.json new file mode 100644 index 0000000000000000000000000000000000000000..3f99bd7d3b07b4bdedc98e7eb23b56ad8c4cf7ac --- /dev/null +++ b/vendor/QmNsoHoCVhgXcv1Yg45jtkMgimxorTAN36fV9AQMFXHHAQ/go-base58/package.json @@ -0,0 +1,9 @@ +{ + "name": "go-base58", + "author": "whyrusleeping", + "version": "1.0.0", + "language": "go", + "gx": { + "dvcsimport": "github.com/jbenet/go-base58" + } +} \ No newline at end of file diff --git a/vendor/QmVBEPpwYNGb5xQW6jPzYgV86KSPRrzhe4hA7o7mtAHZsT/go-utp/LICENSE b/vendor/QmVBEPpwYNGb5xQW6jPzYgV86KSPRrzhe4hA7o7mtAHZsT/go-utp/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..be2cc4dfb609fb6c38f6365ec345bded3350dd63 --- /dev/null +++ b/vendor/QmVBEPpwYNGb5xQW6jPzYgV86KSPRrzhe4hA7o7mtAHZsT/go-utp/LICENSE @@ -0,0 +1,362 @@ +Mozilla Public License, version 2.0 + +1. Definitions + +1.1. "Contributor" + + means each individual or legal entity that creates, contributes to the + creation of, or owns Covered Software. + +1.2. "Contributor Version" + + means the combination of the Contributions of others (if any) used by a + Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + + means Source Code Form to which the initial Contributor has attached the + notice in Exhibit A, the Executable Form of such Source Code Form, and + Modifications of such Source Code Form, in each case including portions + thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + a. that the initial Contributor has attached the notice described in + Exhibit B to the Covered Software; or + + b. that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the terms of + a Secondary License. + +1.6. "Executable Form" + + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + + means a work that combines Covered Software with other material, in a + separate file or files, that is not Covered Software. + +1.8. "License" + + means this document. + +1.9. "Licensable" + + means having the right to grant, to the maximum extent possible, whether + at the time of the initial grant or subsequently, any and all of the + rights conveyed by this License. + +1.10. "Modifications" + + means any of the following: + + a. any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered Software; or + + b. any new file in Source Code Form that contains any Covered Software. + +1.11. "Patent Claims" of a Contributor + + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the License, + by the making, using, selling, offering for sale, having made, import, + or transfer of either its Contributions or its Contributor Version. + +1.12. "Secondary License" + + means either the GNU General Public License, Version 2.0, the GNU Lesser + General Public License, Version 2.1, the GNU Affero General Public + License, Version 3.0, or any later versions of those licenses. + +1.13. "Source Code Form" + + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that controls, is + controlled by, or is under common control with You. For purposes of this + definition, "control" means (a) the power, direct or indirect, to cause + the direction or management of such entity, whether by contract or + otherwise, or (b) ownership of more than fifty percent (50%) of the + outstanding shares or beneficial ownership of such entity. + + +2. License Grants and Conditions + +2.1. Grants + + Each Contributor hereby grants You a world-wide, royalty-free, + non-exclusive license: + + a. under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + + b. under Patent Claims of such Contributor to make, use, sell, offer for + sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + + The licenses granted in Section 2.1 with respect to any Contribution + become effective for each Contribution on the date the Contributor first + distributes such Contribution. + +2.3. Limitations on Grant Scope + + The licenses granted in this Section 2 are the only rights granted under + this License. No additional rights or licenses will be implied from the + distribution or licensing of Covered Software under this License. + Notwithstanding Section 2.1(b) above, no patent license is granted by a + Contributor: + + a. for any code that a Contributor has removed from Covered Software; or + + b. for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + + c. under Patent Claims infringed by Covered Software in the absence of + its Contributions. + + This License does not grant any rights in the trademarks, service marks, + or logos of any Contributor (except as may be necessary to comply with + the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + + No Contributor makes additional grants as a result of Your choice to + distribute the Covered Software under a subsequent version of this + License (see Section 10.2) or under the terms of a Secondary License (if + permitted under the terms of Section 3.3). + +2.5. Representation + + Each Contributor represents that the Contributor believes its + Contributions are its original creation(s) or it has sufficient rights to + grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + + This License is not intended to limit any rights You have under + applicable copyright doctrines of fair use, fair dealing, or other + equivalents. + +2.7. Conditions + + Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in + Section 2.1. + + +3. Responsibilities + +3.1. Distribution of Source Form + + All distribution of Covered Software in Source Code Form, including any + Modifications that You create or to which You contribute, must be under + the terms of this License. You must inform recipients that the Source + Code Form of the Covered Software is governed by the terms of this + License, and how they can obtain a copy of this License. You may not + attempt to alter or restrict the recipients' rights in the Source Code + Form. + +3.2. Distribution of Executable Form + + If You distribute Covered Software in Executable Form then: + + a. such Covered Software must also be made available in Source Code Form, + as described in Section 3.1, and You must inform recipients of the + Executable Form how they can obtain a copy of such Source Code Form by + reasonable means in a timely manner, at a charge no more than the cost + of distribution to the recipient; and + + b. You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter the + recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + + You may create and distribute a Larger Work under terms of Your choice, + provided that You also comply with the requirements of this License for + the Covered Software. If the Larger Work is a combination of Covered + Software with a work governed by one or more Secondary Licenses, and the + Covered Software is not Incompatible With Secondary Licenses, this + License permits You to additionally distribute such Covered Software + under the terms of such Secondary License(s), so that the recipient of + the Larger Work may, at their option, further distribute the Covered + Software under the terms of either this License or such Secondary + License(s). + +3.4. Notices + + You may not remove or alter the substance of any license notices + (including copyright notices, patent notices, disclaimers of warranty, or + limitations of liability) contained within the Source Code Form of the + Covered Software, except that You may alter any license notices to the + extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + + You may choose to offer, and to charge a fee for, warranty, support, + indemnity or liability obligations to one or more recipients of Covered + Software. However, You may do so only on Your own behalf, and not on + behalf of any Contributor. You must make it absolutely clear that any + such warranty, support, indemnity, or liability obligation is offered by + You alone, and You hereby agree to indemnify every Contributor for any + liability incurred by such Contributor as a result of warranty, support, + indemnity or liability terms You offer. You may include additional + disclaimers of warranty and limitations of liability specific to any + jurisdiction. + +4. Inability to Comply Due to Statute or Regulation + + If it is impossible for You to comply with any of the terms of this License + with respect to some or all of the Covered Software due to statute, + judicial order, or regulation then You must: (a) comply with the terms of + this License to the maximum extent possible; and (b) describe the + limitations and the code they affect. Such description must be placed in a + text file included with all distributions of the Covered Software under + this License. Except to the extent prohibited by statute or regulation, + such description must be sufficiently detailed for a recipient of ordinary + skill to be able to understand it. + +5. Termination + +5.1. The rights granted under this License will terminate automatically if You + fail to comply with any of its terms. However, if You become compliant, + then the rights granted under this License from a particular Contributor + are reinstated (a) provisionally, unless and until such Contributor + explicitly and finally terminates Your grants, and (b) on an ongoing + basis, if such Contributor fails to notify You of the non-compliance by + some reasonable means prior to 60 days after You have come back into + compliance. Moreover, Your grants from a particular Contributor are + reinstated on an ongoing basis if such Contributor notifies You of the + non-compliance by some reasonable means, this is the first time You have + received notice of non-compliance with this License from such + Contributor, and You become compliant prior to 30 days after Your receipt + of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent + infringement claim (excluding declaratory judgment actions, + counter-claims, and cross-claims) alleging that a Contributor Version + directly or indirectly infringes any patent, then the rights granted to + You by any and all Contributors for the Covered Software under Section + 2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user + license agreements (excluding distributors and resellers) which have been + validly granted by You or Your distributors under this License prior to + termination shall survive termination. + +6. Disclaimer of Warranty + + Covered Software is provided under this License on an "as is" basis, + without warranty of any kind, either expressed, implied, or statutory, + including, without limitation, warranties that the Covered Software is free + of defects, merchantable, fit for a particular purpose or non-infringing. + The entire risk as to the quality and performance of the Covered Software + is with You. Should any Covered Software prove defective in any respect, + You (not any Contributor) assume the cost of any necessary servicing, + repair, or correction. This disclaimer of warranty constitutes an essential + part of this License. No use of any Covered Software is authorized under + this License except under this disclaimer. + +7. Limitation of Liability + + Under no circumstances and under no legal theory, whether tort (including + negligence), contract, or otherwise, shall any Contributor, or anyone who + distributes Covered Software as permitted above, be liable to You for any + direct, indirect, special, incidental, or consequential damages of any + character including, without limitation, damages for lost profits, loss of + goodwill, work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses, even if such party shall have been + informed of the possibility of such damages. This limitation of liability + shall not apply to liability for death or personal injury resulting from + such party's negligence to the extent applicable law prohibits such + limitation. Some jurisdictions do not allow the exclusion or limitation of + incidental or consequential damages, so this exclusion and limitation may + not apply to You. + +8. Litigation + + Any litigation relating to this License may be brought only in the courts + of a jurisdiction where the defendant maintains its principal place of + business and such litigation shall be governed by laws of that + jurisdiction, without reference to its conflict-of-law provisions. Nothing + in this Section shall prevent a party's ability to bring cross-claims or + counter-claims. + +9. Miscellaneous + + This License represents the complete agreement concerning the subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. Any law or regulation which provides that + the language of a contract shall be construed against the drafter shall not + be used to construe this License against a Contributor. + + +10. Versions of the License + +10.1. New Versions + + Mozilla Foundation is the license steward. Except as provided in Section + 10.3, no one other than the license steward has the right to modify or + publish new versions of this License. Each version will be given a + distinguishing version number. + +10.2. Effect of New Versions + + You may distribute the Covered Software under the terms of the version + of the License under which You originally received the Covered Software, + or under the terms of any subsequent version published by the license + steward. + +10.3. Modified Versions + + If you create software not governed by this License, and you want to + create a new license for such software, you may create and use a + modified version of this License if you rename the license and remove + any references to the name of the license steward (except to note that + such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary + Licenses If You choose to distribute Source Code Form that is + Incompatible With Secondary Licenses under the terms of this version of + the License, the notice described in Exhibit B of this License must be + attached. + +Exhibit A - Source Code Form License Notice + + This Source Code Form is subject to the + terms of the Mozilla Public License, v. + 2.0. If a copy of the MPL was not + distributed with this file, You can + obtain one at + http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular file, +then You may include the notice in a location (such as a LICENSE file in a +relevant directory) where a recipient would be likely to look for such a +notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice + + This Source Code Form is "Incompatible + With Secondary Licenses", as defined by + the Mozilla Public License, v. 2.0. diff --git a/vendor/QmVBEPpwYNGb5xQW6jPzYgV86KSPRrzhe4hA7o7mtAHZsT/go-utp/README.md b/vendor/QmVBEPpwYNGb5xQW6jPzYgV86KSPRrzhe4hA7o7mtAHZsT/go-utp/README.md new file mode 100644 index 0000000000000000000000000000000000000000..01c049e331ff2788f9c6754f9a4e4423e908185e --- /dev/null +++ b/vendor/QmVBEPpwYNGb5xQW6jPzYgV86KSPRrzhe4hA7o7mtAHZsT/go-utp/README.md @@ -0,0 +1,19 @@ +# utp +[![GoDoc](https://godoc.org/github.com/anacrolix/utp?status.svg)](https://godoc.org/github.com/anacrolix/utp) +[![Build Status](https://drone.io/github.com/anacrolix/utp/status.png)](https://drone.io/github.com/anacrolix/utp/latest) + +Package utp implements uTP, the micro transport protocol as used with Bittorrent. It opts for simplicity and reliability over strict adherence to the (poor) spec. + +## Supported + + * Multiple uTP connections switched on a single PacketConn, including those initiated locally. + * Raw access to the PacketConn for non-uTP purposes, like sharing the PacketConn with a DHT implementation. + +## Implementation characteristics + + * Receive window size is used to limit out of order packets received. + * There is no MTU path discovery. The minimum size is always used. + * A fixed 64 slot selective ack window is used in both sending and receiving. + * All received non-ACK packets are ACKed in response. + +Patches welcomed. diff --git a/vendor/QmVBEPpwYNGb5xQW6jPzYgV86KSPRrzhe4hA7o7mtAHZsT/go-utp/cmd/ucat/ucat.go b/vendor/QmVBEPpwYNGb5xQW6jPzYgV86KSPRrzhe4hA7o7mtAHZsT/go-utp/cmd/ucat/ucat.go new file mode 100644 index 0000000000000000000000000000000000000000..b9b591e0fc6c13e312041b4fdd3588ac354e1068 --- /dev/null +++ b/vendor/QmVBEPpwYNGb5xQW6jPzYgV86KSPRrzhe4hA7o7mtAHZsT/go-utp/cmd/ucat/ucat.go @@ -0,0 +1,76 @@ +package main + +import ( + "flag" + "fmt" + "io" + "log" + "net" + "os" + "os/signal" + + "QmWsa476RGjb9scWzcRVts3QZsYjU5Kt6Y9qe8Q3vc5FHR/envpprof" + + "QmVBEPpwYNGb5xQW6jPzYgV86KSPRrzhe4hA7o7mtAHZsT/go-utp" +) + +func main() { + defer envpprof.Stop() + listen := flag.Bool("l", false, "listen") + port := flag.Int("p", 0, "port to listen on") + flag.Parse() + var ( + conn net.Conn + err error + ) + if *listen { + s, err := utp.NewSocket("udp", fmt.Sprintf(":%d", *port)) + if err != nil { + log.Fatal(err) + } + defer s.Close() + conn, err = s.Accept() + if err != nil { + log.Fatal(err) + } + } else { + conn, err = utp.Dial(net.JoinHostPort(flag.Arg(0), flag.Arg(1))) + if err != nil { + log.Fatal(err) + } + } + defer conn.Close() + go func() { + sig := make(chan os.Signal, 1) + signal.Notify(sig, os.Interrupt) + <-sig + conn.Close() + }() + writerDone := make(chan struct{}) + readerDone := make(chan struct{}) + go func() { + defer close(writerDone) + written, err := io.Copy(conn, os.Stdin) + if err != nil { + conn.Close() + log.Fatalf("error after writing %d bytes: %s", written, err) + } + log.Printf("wrote %d bytes", written) + conn.Close() + }() + go func() { + defer close(readerDone) + n, err := io.Copy(os.Stdout, conn) + if err != nil { + log.Fatal(err) + } + log.Printf("received %d bytes", n) + }() + // Technically we should wait until both reading and writing are done. But + // ucat-style binaries terminate abrubtly when read or write is completed, + // and no state remains to clean-up the peer neatly. + select { + case <-writerDone: + case <-readerDone: + } +} diff --git a/vendor/QmVBEPpwYNGb5xQW6jPzYgV86KSPRrzhe4hA7o7mtAHZsT/go-utp/package.json b/vendor/QmVBEPpwYNGb5xQW6jPzYgV86KSPRrzhe4hA7o7mtAHZsT/go-utp/package.json new file mode 100644 index 0000000000000000000000000000000000000000..230a0afcaf2e9c748957b0b80074a46138070af6 --- /dev/null +++ b/vendor/QmVBEPpwYNGb5xQW6jPzYgV86KSPRrzhe4hA7o7mtAHZsT/go-utp/package.json @@ -0,0 +1,21 @@ +{ + "name": "go-utp", + "author": "whyrusleeping", + "version": "1.0.0", + "gxDependencies": [ + { + "name": "jitter", + "hash": "QmbDXAJ4Fzpmqw9kTVPtPGZEsgyn33ipbUQEe8vMUZLnTS", + "version": "1.0.0" + }, + { + "name": "envpprof", + "hash": "QmWsa476RGjb9scWzcRVts3QZsYjU5Kt6Y9qe8Q3vc5FHR", + "version": "1.0.0" + } + ], + "language": "go", + "gx": { + "dvcsimport": "github.com/anacrolix/utp" + } +} \ No newline at end of file diff --git a/vendor/QmVBEPpwYNGb5xQW6jPzYgV86KSPRrzhe4hA7o7mtAHZsT/go-utp/pingpong b/vendor/QmVBEPpwYNGb5xQW6jPzYgV86KSPRrzhe4hA7o7mtAHZsT/go-utp/pingpong new file mode 100644 index 0000000000000000000000000000000000000000..8fca68cf9e84ca823924da86c266a1169711ea21 --- /dev/null +++ b/vendor/QmVBEPpwYNGb5xQW6jPzYgV86KSPRrzhe4hA7o7mtAHZsT/go-utp/pingpong @@ -0,0 +1,68 @@ +# This shell script uses nc-like executables to send and receive the file at +# $1, and prints the checksums. 3 such executables are +# github.com/h2so5/utp/ucat, invoked as h2so5-ucat, libutp-ucat, which is the +# ucat or ucat-static generated by the C++ libutp, and lastly, ./cmd/ucat from +# this repository. A good file in my experiments is no more than a few 100MB, +# or you'll be waiting a while. + +set -eu +# set -x + +# Passed to invocations of godo for package ./cmd/ucat. +#GODOFLAGS=-race + +#export GO_UTP_PACKET_DROP=0.1 +export GOPPROF= + +# Invokes the implementation to test against. If there's an arg, then it's +# expected to listen. +function other_ucat() { + if [[ $# != 0 ]]; then + libutp-ucat -l -p "$port" + # h2so5-ucat -l :"$port" + else + libutp-ucat localhost "$port" + # h2so5-ucat localhost:"$port" + fi +} + +function md5cmd() { + (which md5sum > /dev/null && md5sum "$@") || (which md5 > /dev/null && md5 "$@") || md5sum "$@" +} + +# Check what the correct result is. +md5cmd "$1" + +rate() { + pv -a -W -b +} + +port=4000 + +echo 'utp->other_ucat' +# Send from this uTP implementation to another client. +other_ucat -l | rate | md5cmd & +# sleep 1 +godo ${GODOFLAGS-} ./cmd/ucat localhost "$port" < "$1" +wait + +echo 'other_ucat->utp' +# Send from the other implementation, to this one. +GO_UTP_LOGGING=0 godo ${GODOFLAGS-} ./cmd/ucat -l -p "$port" | rate | md5cmd & +# Never receive from h2so5's ucat without a small sleep first. Don't know why. +sleep 1 +other_ucat < "$1" +wait + +echo 'libutp->libutp' +libutp-ucat -l -p "$port" | rate | md5cmd & +libutp-ucat localhost "$port" < "$1" +wait + +echo 'utp->utp' +godo ./cmd/ucat -l -p "$port" | rate | md5cmd & +sleep 1 +godo ./cmd/ucat localhost "$port" < "$1" +wait + +# Now check the hashes match (yes you). diff --git a/vendor/QmVBEPpwYNGb5xQW6jPzYgV86KSPRrzhe4hA7o7mtAHZsT/go-utp/utp.go b/vendor/QmVBEPpwYNGb5xQW6jPzYgV86KSPRrzhe4hA7o7mtAHZsT/go-utp/utp.go new file mode 100644 index 0000000000000000000000000000000000000000..7f6e2af7f60bae3b133343cd1f13dfde8c380600 --- /dev/null +++ b/vendor/QmVBEPpwYNGb5xQW6jPzYgV86KSPRrzhe4hA7o7mtAHZsT/go-utp/utp.go @@ -0,0 +1,1443 @@ +// Package utp implements uTP, the micro transport protocol as used with +// Bittorrent. It opts for simplicity and reliability over strict adherence to +// the (poor) spec. It allows using the underlying OS-level transport despite +// dispatching uTP on top to allow for example, shared socket use with DHT. +// Additionally, multiple uTP connections can share the same OS socket, to +// truly realize uTP's claim to be light on system and network switching +// resources. +// +// Socket is a wrapper of net.UDPConn, and performs dispatching of uTP packets +// to attached uTP Conns. Dial and Accept is done via Socket. Conn implements +// net.Conn over uTP, via aforementioned Socket. +package utp + +import ( + "encoding/binary" + "errors" + "expvar" + "fmt" + "io" + "log" + "math" + "math/rand" + "net" + "os" + "strconv" + "sync" + "time" + + "QmbDXAJ4Fzpmqw9kTVPtPGZEsgyn33ipbUQEe8vMUZLnTS/jitter" +) + +const ( + // Maximum received SYNs that haven't been accepted. If more SYNs are + // received, a pseudo randomly selected SYN is replied to with a reset to + // make room. + backlog = 50 + + // IPv6 min MTU is 1280, -40 for IPv6 header, and ~8 for fragment header? + minMTU = 1232 + recvWindow = 1 << 18 // 256KiB + // uTP header of 20, +2 for the next extension, and 8 bytes of selective + // ACK. + maxHeaderSize = 30 + maxPayloadSize = minMTU - maxHeaderSize + maxRecvSize = 0x2000 + + // Maximum out-of-order packets to buffer. + maxUnackedInbound = 256 + maxUnackedSends = 256 +) + +var ( + ackSkippedResends = expvar.NewInt("utpAckSkippedResends") + // Inbound packets processed by a Conn. + deliveriesProcessed = expvar.NewInt("utpDeliveriesProcessed") + sentStatePackets = expvar.NewInt("utpSentStatePackets") + unusedReads = expvar.NewInt("utpUnusedReads") + sendBufferPool = sync.Pool{ + New: func() interface{} { return make([]byte, minMTU) }, + } + // This is the latency we assume on new connections. It should be higher + // than the latency we expect on most connections to prevent excessive + // resending to peers that take a long time to respond, before we've got a + // better idea of their actual latency. + initialLatency = 400 * time.Millisecond + // If a write isn't acked within this period, destroy the connection. + writeTimeout = 15 * time.Second + packetReadTimeout = 2 * time.Minute +) + +type deadlineCallback struct { + deadline time.Time + timer *time.Timer + callback func() +} + +func (me *deadlineCallback) deadlineExceeded() bool { + return !me.deadline.IsZero() && !time.Now().Before(me.deadline) +} + +func (me *deadlineCallback) updateTimer() { + if me.timer != nil { + me.timer.Stop() + } + if me.deadline.IsZero() { + return + } + if me.callback == nil { + panic("deadline callback is nil") + } + me.timer = time.AfterFunc(me.deadline.Sub(time.Now()), me.callback) +} + +func (me *deadlineCallback) setDeadline(t time.Time) { + me.deadline = t + me.updateTimer() +} + +func (me *deadlineCallback) setCallback(f func()) { + me.callback = f + me.updateTimer() +} + +type connDeadlines struct { + // mu sync.Mutex + read, write deadlineCallback +} + +func (c *connDeadlines) SetDeadline(t time.Time) error { + c.read.setDeadline(t) + c.write.setDeadline(t) + return nil +} + +func (c *connDeadlines) SetReadDeadline(t time.Time) error { + c.read.setDeadline(t) + return nil +} + +func (c *connDeadlines) SetWriteDeadline(t time.Time) error { + c.write.setDeadline(t) + return nil +} + +// Strongly-type guarantee of resolved network address. +type resolvedAddrStr string + +// Uniquely identifies any uTP connection on top of the underlying packet +// stream. +type connKey struct { + remoteAddr resolvedAddrStr + connID uint16 +} + +// A Socket wraps a net.PacketConn, diverting uTP packets to its child uTP +// Conns. +type Socket struct { + mu sync.RWMutex + event sync.Cond + pc net.PacketConn + conns map[connKey]*Conn + backlog map[syn]struct{} + reads chan read + closing bool + + unusedReads chan read + connDeadlines + // If a read error occurs on the underlying net.PacketConn, it is put + // here. This is because reading is done in its own goroutine to dispatch + // to uTP Conns. + ReadErr error +} + +type read struct { + data []byte + from net.Addr +} + +type syn struct { + seq_nr, conn_id uint16 + addr string +} + +const ( + extensionTypeSelectiveAck = 1 +) + +type extensionField struct { + Type byte + Bytes []byte +} + +type header struct { + Type st + Version int + ConnID uint16 + Timestamp uint32 + TimestampDiff uint32 + WndSize uint32 + SeqNr uint16 + AckNr uint16 + Extensions []extensionField +} + +var ( + mu sync.RWMutex + logLevel = 0 + artificialPacketDropChance = 0.0 +) + +func init() { + logLevel, _ = strconv.Atoi(os.Getenv("GO_UTP_LOGGING")) + fmt.Sscanf(os.Getenv("GO_UTP_PACKET_DROP"), "%f", &artificialPacketDropChance) +} + +var ( + errClosed = errors.New("closed") + errNotImplemented = errors.New("not implemented") + errTimeout net.Error = timeoutError{"i/o timeout"} + errAckTimeout = timeoutError{"timed out waiting for ack"} +) + +type timeoutError struct { + msg string +} + +func (me timeoutError) Timeout() bool { return true } +func (me timeoutError) Error() string { return me.msg } +func (me timeoutError) Temporary() bool { return false } + +func unmarshalExtensions(_type byte, b []byte) (n int, ef []extensionField, err error) { + for _type != 0 { + if _type != extensionTypeSelectiveAck { + // An extension type that is not known to us. Generally we're + // unmarshalling an packet that isn't actually uTP but we don't + // yet know for sure until we try to deliver it. + + // logonce.Stderr.Printf("utp extension %d", _type) + } + if len(b) < 2 || len(b) < int(b[1])+2 { + err = fmt.Errorf("buffer ends prematurely: %x", b) + return + } + ef = append(ef, extensionField{ + Type: _type, + Bytes: append([]byte{}, b[2:int(b[1])+2]...), + }) + _type = b[0] + n += 2 + int(b[1]) + b = b[2+int(b[1]):] + } + return +} + +var errInvalidHeader = errors.New("invalid header") + +func (h *header) Unmarshal(b []byte) (n int, err error) { + h.Type = st(b[0] >> 4) + h.Version = int(b[0] & 0xf) + if h.Type > stMax || h.Version != 1 { + err = errInvalidHeader + return + } + n, h.Extensions, err = unmarshalExtensions(b[1], b[20:]) + if err != nil { + return + } + h.ConnID = binary.BigEndian.Uint16(b[2:4]) + h.Timestamp = binary.BigEndian.Uint32(b[4:8]) + h.TimestampDiff = binary.BigEndian.Uint32(b[8:12]) + h.WndSize = binary.BigEndian.Uint32(b[12:16]) + h.SeqNr = binary.BigEndian.Uint16(b[16:18]) + h.AckNr = binary.BigEndian.Uint16(b[18:20]) + n += 20 + return +} + +func (h *header) Marshal() (ret []byte) { + hLen := 20 + func() (ret int) { + for _, ext := range h.Extensions { + ret += 2 + len(ext.Bytes) + } + return + }() + ret = sendBufferPool.Get().([]byte)[:hLen:minMTU] + // ret = make([]byte, hLen, minMTU) + p := ret // Used for manipulating ret. + p[0] = byte(h.Type<<4 | 1) + binary.BigEndian.PutUint16(p[2:4], h.ConnID) + binary.BigEndian.PutUint32(p[4:8], h.Timestamp) + binary.BigEndian.PutUint32(p[8:12], h.TimestampDiff) + binary.BigEndian.PutUint32(p[12:16], h.WndSize) + binary.BigEndian.PutUint16(p[16:18], h.SeqNr) + binary.BigEndian.PutUint16(p[18:20], h.AckNr) + // Pointer to the last type field so the next extension can set it. + _type := &p[1] + // We're done with the basic header. + p = p[20:] + for _, ext := range h.Extensions { + *_type = ext.Type + // The next extension's type will go here. + _type = &p[0] + p[1] = uint8(len(ext.Bytes)) + if int(p[1]) != copy(p[2:], ext.Bytes) { + panic("unexpected extension length") + } + p = p[2+len(ext.Bytes):] + } + if len(p) != 0 { + panic("header length changed") + } + return +} + +var ( + _ net.Listener = &Socket{} + _ net.PacketConn = &Socket{} +) + +type st int + +func (me st) String() string { + switch me { + case stData: + return "stData" + case stFin: + return "stFin" + case stState: + return "stState" + case stReset: + return "stReset" + case stSyn: + return "stSyn" + default: + panic(fmt.Sprintf("%d", me)) + } +} + +const ( + stData st = 0 + stFin = 1 + stState = 2 + stReset = 3 + stSyn = 4 + + // Used for validating packet headers. + stMax = stSyn +) + +// Conn is a uTP stream and implements net.Conn. It owned by a Socket, which +// handles dispatching packets to and from Conns. +type Conn struct { + mu sync.Mutex + event sync.Cond + + recv_id, send_id uint16 + seq_nr, ack_nr uint16 + lastAck uint16 + lastTimeDiff uint32 + peerWndSize uint32 + cur_window uint32 + + // Data waiting to be Read. + readBuf []byte + + socket *Socket + remoteAddr net.Addr + // The uTP timestamp. + startTimestamp uint32 + // When the conn was allocated. + created time.Time + + sentSyn bool + synAcked bool + gotFin bool + wroteFin bool + finAcked bool + err error + closing bool + closed bool + + unackedSends []*send + // Inbound payloads, the first is ack_nr+1. + inbound []recv + inboundWnd uint32 + packetsIn chan packet + connDeadlines + latencies []time.Duration + pendingSendState bool +} + +type send struct { + acked bool // Closed with Conn lock. + payloadSize uint32 + started time.Time + // This send was skipped in a selective ack. + resend func() + timedOut func() + conn *Conn + + acksSkipped int + resendTimer *time.Timer + numResends int +} + +func (s *send) Ack() (latency time.Duration, first bool) { + s.resendTimer.Stop() + if s.acked { + return + } + s.acked = true + s.conn.event.Broadcast() + first = true + latency = time.Since(s.started) + return +} + +type recv struct { + seen bool + data []byte + Type st +} + +var ( + _ net.Conn = &Conn{} +) + +func (c *Conn) age() time.Duration { + return time.Since(c.created) +} + +func (c *Conn) timestamp() uint32 { + return nowTimestamp() - c.startTimestamp +} + +// Create a Socket, using the provided net.PacketConn. If you want to retain +// use of the net.PacketConn after the Socket closes it, override your +// net.PacketConn's Close method. +func NewSocketFromPacketConn(pc net.PacketConn) (s *Socket, err error) { + s = &Socket{ + backlog: make(map[syn]struct{}, backlog), + reads: make(chan read, 100), + pc: pc, + + unusedReads: make(chan read, 100), + } + s.event.L = &s.mu + go s.reader() + go s.dispatcher() + return +} + +// addr is used to create a listening UDP conn which becomes the underlying +// net.PacketConn for the Socket. +func NewSocket(network, addr string) (s *Socket, err error) { + pc, err := net.ListenPacket(network, addr) + if err != nil { + return + } + return NewSocketFromPacketConn(pc) +} + +func packetDebugString(h *header, payload []byte) string { + return fmt.Sprintf("%s->%d: %q", h.Type, h.ConnID, payload) +} + +func (s *Socket) reader() { + defer close(s.reads) + var b [maxRecvSize]byte + for { + if s.pc == nil { + break + } + n, addr, err := s.pc.ReadFrom(b[:]) + if err != nil { + s.mu.Lock() + if !s.closing { + s.ReadErr = err + } + s.mu.Unlock() + return + } + var nilB []byte + s.reads <- read{append(nilB, b[:n:n]...), addr} + } +} + +func (s *Socket) unusedRead(read read) { + unusedReads.Add(1) + select { + case s.unusedReads <- read: + default: + // Drop the packet. + } +} + +func stringAddr(s string) net.Addr { + addr, err := net.ResolveUDPAddr("udp", s) + if err != nil { + panic(err) + } + return addr +} + +func (s *Socket) pushBacklog(syn syn) { + if _, ok := s.backlog[syn]; ok { + return + } + for k := range s.backlog { + if len(s.backlog) < backlog { + break + } + delete(s.backlog, k) + // A syn is sent on the remote's recv_id, so this is where we can send + // the reset. + s.reset(stringAddr(k.addr), k.seq_nr, k.conn_id) + } + s.backlog[syn] = struct{}{} + s.event.Broadcast() +} + +func (s *Socket) dispatcher() { + for { + select { + case read, ok := <-s.reads: + if !ok { + return + } + if len(read.data) < 20 { + s.unusedRead(read) + continue + } + s.dispatch(read) + } + } +} + +func (s *Socket) dispatch(read read) { + b := read.data + addr := read.from + var h header + hEnd, err := h.Unmarshal(b) + if logLevel >= 1 { + log.Printf("recvd utp msg: %s", packetDebugString(&h, b[hEnd:])) + } + if err != nil || h.Type > stMax || h.Version != 1 { + s.unusedRead(read) + return + } + s.mu.Lock() + defer s.mu.Unlock() + c, ok := s.conns[connKey{resolvedAddrStr(addr.String()), func() (recvID uint16) { + recvID = h.ConnID + // If a SYN is resent, its connection ID field will be one lower + // than we expect. + if h.Type == stSyn { + recvID++ + } + return + }()}] + if ok { + if h.Type == stSyn { + if h.ConnID == c.send_id-2 { + // This is a SYN for connection that cannot exist locally. The + // connection the remote wants to establish here with the proposed + // recv_id, already has an existing connection that was dialled + // *out* from this socket, which is why the send_id is 1 higher, + // rather than 1 lower than the recv_id. + log.Print("resetting conflicting syn") + s.reset(addr, h.SeqNr, h.ConnID) + return + } else if h.ConnID != c.send_id { + panic("bad assumption") + } + } + c.deliver(h, b[hEnd:]) + return + } + if h.Type == stSyn { + if logLevel >= 1 { + log.Printf("adding SYN to backlog") + } + syn := syn{ + seq_nr: h.SeqNr, + conn_id: h.ConnID, + addr: addr.String(), + } + s.pushBacklog(syn) + return + } else if h.Type != stReset { + // This is an unexpected packet. We'll send a reset, but also pass + // it on. + // log.Print("resetting unexpected packet") + // I don't think you can reset on the received packets ConnID if it isn't a SYN, as the send_id will differ in this case. + s.reset(addr, h.SeqNr, h.ConnID) + s.reset(addr, h.SeqNr, h.ConnID-1) + s.reset(addr, h.SeqNr, h.ConnID+1) + } + s.unusedRead(read) +} + +// Send a reset in response to a packet with the given header. +func (s *Socket) reset(addr net.Addr, ackNr, connId uint16) { + go s.writeTo((&header{ + Type: stReset, + Version: 1, + ConnID: connId, + AckNr: ackNr, + }).Marshal(), addr) +} + +// Attempt to connect to a remote uTP listener, creating a Socket just for +// this connection. +func Dial(addr string) (net.Conn, error) { + return DialTimeout(addr, 0) +} + +// Same as Dial with a timeout parameter. +func DialTimeout(addr string, timeout time.Duration) (nc net.Conn, err error) { + s, err := NewSocket("udp", ":0") + if err != nil { + return + } + return s.DialTimeout(addr, timeout) + +} + +// Return a recv_id that should be free. Handling the case where it isn't is +// deferred to a more appropriate function. +func (s *Socket) newConnID(remoteAddr resolvedAddrStr) (id uint16) { + // Rather than use math.Rand, which requires generating all the IDs up + // front and allocating a slice, we do it on the stack, generating the IDs + // only as required. To do this, we use the fact that the array is + // default-initialized. IDs that are 0, are actually their index in the + // array. IDs that are non-zero, are +1 from their intended ID. + var idsBack [0x10000]int + ids := idsBack[:] + for len(ids) != 0 { + // Pick the next ID from the untried ids. + i := rand.Intn(len(ids)) + id = uint16(ids[i]) + // If it's zero, then treat it as though the index i was the ID. + // Otherwise the value we get is the ID+1. + if id == 0 { + id = uint16(i) + } else { + id-- + } + // Check there's no connection using this ID for its recv_id... + _, ok1 := s.conns[connKey{remoteAddr, id}] + // and if we're connecting to our own Socket, that there isn't a Conn + // already receiving on what will correspond to our send_id. Note that + // we just assume that we could be connecting to our own Socket. This + // will halve the available connection IDs to each distinct remote + // address. Presumably that's ~0x8000, down from ~0x10000. + _, ok2 := s.conns[connKey{remoteAddr, id + 1}] + _, ok4 := s.conns[connKey{remoteAddr, id - 1}] + if !ok1 && !ok2 && !ok4 { + return + } + // The set of possible IDs is shrinking. The highest one will be lost, so + // it's moved to the location of the one we just tried. + ids[i] = len(ids) // Conveniently already +1. + // And shrink. + ids = ids[:len(ids)-1] + } + return +} + +func (c *Conn) sendPendingState() { + if !c.pendingSendState { + return + } + if c.closed { + c.sendReset() + } else { + c.sendState() + } +} + +func (s *Socket) newConn(addr net.Addr) (c *Conn) { + c = &Conn{ + socket: s, + remoteAddr: addr, + created: time.Now(), + packetsIn: make(chan packet, 100), + } + c.event.L = &c.mu + c.mu.Lock() + c.connDeadlines.read.setCallback(func() { + c.mu.Lock() + c.event.Broadcast() + c.mu.Unlock() + }) + c.connDeadlines.write.setCallback(func() { + c.mu.Lock() + c.event.Broadcast() + c.mu.Unlock() + }) + c.mu.Unlock() + go c.deliveryProcessor() + return +} + +func (s *Socket) Dial(addr string) (net.Conn, error) { + return s.DialTimeout(addr, 0) +} + +func (s *Socket) DialTimeout(addr string, timeout time.Duration) (nc net.Conn, err error) { + netAddr, err := net.ResolveUDPAddr("udp", addr) + if err != nil { + return + } + + s.mu.Lock() + c := s.newConn(netAddr) + c.recv_id = s.newConnID(resolvedAddrStr(netAddr.String())) + c.send_id = c.recv_id + 1 + if logLevel >= 1 { + log.Printf("dial registering addr: %s", netAddr.String()) + } + if !s.registerConn(c.recv_id, resolvedAddrStr(netAddr.String()), c) { + err = errors.New("couldn't register new connection") + log.Println(c.recv_id, netAddr.String()) + for k, c := range s.conns { + log.Println(k, c, c.age()) + } + log.Printf("that's %d connections", len(s.conns)) + } + s.mu.Unlock() + if err != nil { + return + } + + connErr := make(chan error, 1) + go func() { + connErr <- c.connect() + }() + var timeoutCh <-chan time.Time + if timeout != 0 { + timeoutCh = time.After(timeout) + } + select { + case err = <-connErr: + case <-timeoutCh: + err = errTimeout + } + if err == nil { + nc = c + } else { + c.Close() + } + return +} + +func (c *Conn) wndSize() uint32 { + if len(c.inbound) > maxUnackedInbound/2 { + return 0 + } + buffered := uint32(len(c.readBuf)) + c.inboundWnd + if buffered > recvWindow { + return 0 + } + return recvWindow - buffered +} + +func nowTimestamp() uint32 { + return uint32(time.Now().UnixNano() / int64(time.Microsecond)) +} + +// Send the given payload with an up to date header. +func (c *Conn) send(_type st, connID uint16, payload []byte, seqNr uint16) (err error) { + // Always selectively ack the first 64 packets. Don't bother with rest for + // now. + selAck := selectiveAckBitmask(make([]byte, 8)) + for i := 1; i < 65; i++ { + if len(c.inbound) <= i { + break + } + if c.inbound[i].seen { + selAck.SetBit(i - 1) + } + } + h := header{ + Type: _type, + Version: 1, + ConnID: connID, + SeqNr: seqNr, + AckNr: c.ack_nr, + WndSize: c.wndSize(), + Timestamp: c.timestamp(), + TimestampDiff: c.lastTimeDiff, + // Currently always send an 8 byte selective ack. + Extensions: []extensionField{{ + Type: extensionTypeSelectiveAck, + Bytes: selAck, + }}, + } + p := h.Marshal() + // Extension headers are currently fixed in size. + if len(p) != maxHeaderSize { + panic("header has unexpected size") + } + p = append(p, payload...) + if logLevel >= 1 { + log.Printf("writing utp msg to %s: %s", c.remoteAddr, packetDebugString(&h, payload)) + } + n1, err := c.socket.writeTo(p, c.remoteAddr) + if err != nil { + return + } + if n1 != len(p) { + panic(n1) + } + c.unpendSendState() + return +} + +func (me *Conn) unpendSendState() { + me.pendingSendState = false +} + +func (c *Conn) pendSendState() { + c.pendingSendState = true +} + +func (me *Socket) writeTo(b []byte, addr net.Addr) (n int, err error) { + mu.RLock() + apdc := artificialPacketDropChance + mu.RUnlock() + if apdc != 0 { + if rand.Float64() < apdc { + n = len(b) + return + } + } + n, err = me.pc.WriteTo(b, addr) + return +} + +func (s *send) timeoutResend() { + if time.Since(s.started) >= writeTimeout { + s.timedOut() + return + } + s.conn.mu.Lock() + defer s.conn.mu.Unlock() + if s.acked || s.conn.closed { + return + } + rt := s.conn.resendTimeout() + go s.resend() + s.numResends++ + s.resendTimer.Reset(rt * time.Duration(s.numResends)) +} + +func (me *Conn) writeSyn() { + if me.sentSyn { + panic("already sent syn") + } + me.write(stSyn, me.recv_id, nil, me.seq_nr) + return +} + +func (c *Conn) write(_type st, connID uint16, payload []byte, seqNr uint16) (n int) { + switch _type { + case stSyn, stFin, stData: + default: + panic(_type) + } + if c.wroteFin { + panic("can't write after fin") + } + if len(payload) > maxPayloadSize { + payload = payload[:maxPayloadSize] + } + err := c.send(_type, connID, payload, seqNr) + if err != nil { + c.destroy(fmt.Errorf("error sending packet: %s", err)) + return + } + n = len(payload) + // Copy payload so caller to write can continue to use the buffer. + if payload != nil { + payload = append(sendBufferPool.Get().([]byte)[:0:minMTU], payload...) + } + send := &send{ + payloadSize: uint32(len(payload)), + started: time.Now(), + resend: func() { + c.mu.Lock() + err := c.send(_type, connID, payload, seqNr) + if err != nil { + log.Printf("error resending packet: %s", err) + } + c.mu.Unlock() + }, + timedOut: func() { + c.mu.Lock() + c.destroy(errAckTimeout) + c.mu.Unlock() + }, + conn: c, + } + send.resendTimer = time.AfterFunc(c.resendTimeout(), send.timeoutResend) + c.unackedSends = append(c.unackedSends, send) + c.cur_window += send.payloadSize + c.seq_nr++ + return +} + +func (c *Conn) latency() (ret time.Duration) { + if len(c.latencies) == 0 { + return initialLatency + } + for _, l := range c.latencies { + ret += l + } + ret = (ret + time.Duration(len(c.latencies)) - 1) / time.Duration(len(c.latencies)) + return +} + +func (c *Conn) numUnackedSends() (num int) { + for _, s := range c.unackedSends { + if !s.acked { + num++ + } + } + return +} + +func (c *Conn) sendState() { + c.send(stState, c.send_id, nil, c.seq_nr) + sentStatePackets.Add(1) +} + +func (c *Conn) sendReset() { + c.send(stReset, c.send_id, nil, c.seq_nr) +} + +func seqLess(a, b uint16) bool { + if b < 0x8000 { + return a < b || a >= b-0x8000 + } else { + return a < b && a >= b-0x8000 + } +} + +// Ack our send with the given sequence number. +func (c *Conn) ack(nr uint16) { + if !seqLess(c.lastAck, nr) { + // Already acked. + return + } + i := nr - c.lastAck - 1 + if int(i) >= len(c.unackedSends) { + log.Printf("got ack ahead of syn (%x > %x)", nr, c.seq_nr-1) + return + } + s := c.unackedSends[i] + latency, first := s.Ack() + if first { + c.cur_window -= s.payloadSize + c.latencies = append(c.latencies, latency) + if len(c.latencies) > 10 { + c.latencies = c.latencies[len(c.latencies)-10:] + } + } + for { + if len(c.unackedSends) == 0 { + break + } + if !c.unackedSends[0].acked { + // Can't trim unacked sends any further. + return + } + // Trim the front of the unacked sends. + c.unackedSends = c.unackedSends[1:] + c.lastAck++ + } + c.event.Broadcast() +} + +func (c *Conn) ackTo(nr uint16) { + if !seqLess(nr, c.seq_nr) { + return + } + for seqLess(c.lastAck, nr) { + c.ack(c.lastAck + 1) + } +} + +type selectiveAckBitmask []byte + +func (me selectiveAckBitmask) NumBits() int { + return len(me) * 8 +} + +func (me selectiveAckBitmask) SetBit(index int) { + me[index/8] |= 1 << uint(index%8) +} + +func (me selectiveAckBitmask) BitIsSet(index int) bool { + return me[index/8]>>uint(index%8)&1 == 1 +} + +// Return the send state for the sequence number. Returns nil if there's no +// outstanding send for that sequence number. +func (c *Conn) seqSend(seqNr uint16) *send { + if !seqLess(c.lastAck, seqNr) { + // Presumably already acked. + return nil + } + i := int(seqNr - c.lastAck - 1) + if i >= len(c.unackedSends) { + // No such send. + return nil + } + return c.unackedSends[i] +} + +func (c *Conn) resendTimeout() time.Duration { + l := c.latency() + ret := jitter.Duration(3*l, l) + return ret +} + +func (c *Conn) ackSkipped(seqNr uint16) { + send := c.seqSend(seqNr) + if send == nil { + return + } + send.acksSkipped++ + switch send.acksSkipped { + case 3, 60: + ackSkippedResends.Add(1) + go send.resend() + send.resendTimer.Reset(c.resendTimeout() * time.Duration(send.numResends)) + default: + } +} + +type packet struct { + h header + payload []byte +} + +func (c *Conn) deliver(h header, payload []byte) { + c.packetsIn <- packet{h, payload} +} + +func (c *Conn) deliveryProcessor() { + timeout := time.NewTimer(math.MaxInt64) + for { + timeout.Reset(packetReadTimeout) + select { + case p, ok := <-c.packetsIn: + if !ok { + return + } + c.processDelivery(p.h, p.payload) + timeout := time.After(500 * time.Microsecond) + batched: + for { + select { + case p, ok := <-c.packetsIn: + if !ok { + break batched + } + c.processDelivery(p.h, p.payload) + case <-timeout: + break batched + } + } + c.mu.Lock() + c.sendPendingState() + c.mu.Unlock() + case <-timeout.C: + c.mu.Lock() + c.destroy(errors.New("no packet read timeout")) + c.mu.Unlock() + } + } +} + +func (c *Conn) updateStates() { + if c.wroteFin && len(c.unackedSends) <= 1 && c.gotFin { + c.closed = true + c.event.Broadcast() + } +} + +func (c *Conn) processDelivery(h header, payload []byte) { + deliveriesProcessed.Add(1) + c.mu.Lock() + defer c.mu.Unlock() + defer c.updateStates() + defer c.event.Broadcast() + c.assertHeader(h) + c.peerWndSize = h.WndSize + c.applyAcks(h) + if h.Timestamp == 0 { + c.lastTimeDiff = 0 + } else { + c.lastTimeDiff = c.timestamp() - h.Timestamp + } + + if h.Type == stReset { + c.destroy(errors.New("peer reset")) + return + } + if !c.synAcked { + if h.Type != stState { + return + } + c.synAcked = true + c.ack_nr = h.SeqNr - 1 + return + } + if h.Type == stState { + return + } + c.pendSendState() + if !seqLess(c.ack_nr, h.SeqNr) { + // Already received this packet. + return + } + inboundIndex := int(h.SeqNr - c.ack_nr - 1) + if inboundIndex < len(c.inbound) && c.inbound[inboundIndex].seen { + // Already received this packet. + return + } + // Derived from running in production: + // grep -oP '(?<=packet out of order, index=)\d+' log | sort -n | uniq -c + // 64 should correspond to 8 bytes of selective ack. + if inboundIndex >= maxUnackedInbound { + // Discard packet too far ahead. + if logLevel >= 1 { + log.Printf("received packet from %s %d ahead of next seqnr (%x > %x)", c.remoteAddr, inboundIndex, h.SeqNr, c.ack_nr+1) + } + return + } + // Extend inbound so the new packet has a place. + for inboundIndex >= len(c.inbound) { + c.inbound = append(c.inbound, recv{}) + } + c.inbound[inboundIndex] = recv{true, payload, h.Type} + c.inboundWnd += uint32(len(payload)) + c.processInbound() +} + +func (c *Conn) applyAcks(h header) { + c.ackTo(h.AckNr) + for _, ext := range h.Extensions { + switch ext.Type { + case extensionTypeSelectiveAck: + c.ackSkipped(h.AckNr + 1) + bitmask := selectiveAckBitmask(ext.Bytes) + for i := 0; i < bitmask.NumBits(); i++ { + if bitmask.BitIsSet(i) { + nr := h.AckNr + 2 + uint16(i) + // log.Printf("selectively acked %d", nr) + c.ack(nr) + } else { + c.ackSkipped(h.AckNr + 2 + uint16(i)) + } + } + } + } +} + +func (c *Conn) assertHeader(h header) { + if h.Type == stSyn { + if h.ConnID != c.send_id { + panic(fmt.Sprintf("%d != %d", h.ConnID, c.send_id)) + } + } else { + if h.ConnID != c.recv_id { + panic("erroneous delivery") + } + } +} + +func (c *Conn) processInbound() { + // Consume consecutive next packets. + for !c.gotFin && len(c.inbound) > 0 && c.inbound[0].seen { + c.ack_nr++ + p := c.inbound[0] + c.inbound = c.inbound[1:] + c.inboundWnd -= uint32(len(p.data)) + c.readBuf = append(c.readBuf, p.data...) + if p.Type == stFin { + c.gotFin = true + } + } +} + +func (c *Conn) waitAck(seq uint16) { + send := c.seqSend(seq) + if send == nil { + return + } + for !send.acked && !c.closed { + c.event.Wait() + } + return +} + +func (c *Conn) connect() (err error) { + c.mu.Lock() + defer c.mu.Unlock() + c.seq_nr = 1 + c.writeSyn() + c.sentSyn = true + if logLevel >= 2 { + log.Printf("sent syn") + } + // c.seq_nr++ + c.waitAck(1) + if c.err != nil { + err = c.err + } + c.synAcked = true + c.event.Broadcast() + return err +} + +func (s *Socket) detacher(c *Conn, key connKey) { + c.mu.Lock() + for !c.closed { + c.event.Wait() + } + c.mu.Unlock() + s.mu.Lock() + defer s.mu.Unlock() + if s.conns[key] != c { + panic("conn changed") + } + delete(s.conns, key) + close(c.packetsIn) + s.event.Broadcast() + if s.closing { + s.teardown() + } +} + +// Returns true if the connection was newly registered, false otherwise. +func (s *Socket) registerConn(recvID uint16, remoteAddr resolvedAddrStr, c *Conn) bool { + if s.conns == nil { + s.conns = make(map[connKey]*Conn) + } + key := connKey{remoteAddr, recvID} + if _, ok := s.conns[key]; ok { + return false + } + s.conns[key] = c + go s.detacher(c, key) + return true +} + +func (s *Socket) nextSyn() (syn syn, ok bool) { + s.mu.Lock() + defer s.mu.Unlock() + for { + if s.closing { + return + } + for k := range s.backlog { + syn = k + delete(s.backlog, k) + ok = true + return + } + s.event.Wait() + } +} + +// Accept and return a new uTP connection. +func (s *Socket) Accept() (c net.Conn, err error) { + for { + syn, ok := s.nextSyn() + if !ok { + err = errClosed + return + } + s.mu.Lock() + _c := s.newConn(stringAddr(syn.addr)) + _c.send_id = syn.conn_id + _c.recv_id = _c.send_id + 1 + _c.seq_nr = uint16(rand.Int()) + _c.lastAck = _c.seq_nr - 1 + _c.ack_nr = syn.seq_nr + _c.sentSyn = true + _c.synAcked = true + if !s.registerConn(_c.recv_id, resolvedAddrStr(syn.addr), _c) { + // SYN that triggered this accept duplicates existing connection. + // Ack again in case the SYN was a resend. + _c = s.conns[connKey{resolvedAddrStr(syn.addr), _c.recv_id}] + if _c.send_id != syn.conn_id { + panic(":|") + } + _c.sendState() + s.mu.Unlock() + continue + } + _c.sendState() + // _c.seq_nr++ + c = _c + s.mu.Unlock() + return + } +} + +// The address we're listening on for new uTP connections. +func (s *Socket) Addr() net.Addr { + return s.pc.LocalAddr() +} + +func (s *Socket) Close() error { + s.mu.Lock() + defer s.mu.Unlock() + s.closing = true + s.event.Broadcast() + return s.teardown() +} + +func (s *Socket) teardown() (err error) { + if len(s.conns) == 0 { + s.event.Broadcast() + err = s.pc.Close() + } + return +} + +func (s *Socket) LocalAddr() net.Addr { + return s.pc.LocalAddr() +} + +func (s *Socket) ReadFrom(p []byte) (n int, addr net.Addr, err error) { + read, ok := <-s.unusedReads + if !ok { + err = io.EOF + } + n = copy(p, read.data) + addr = read.from + return +} + +func (s *Socket) WriteTo(b []byte, addr net.Addr) (int, error) { + return s.pc.WriteTo(b, addr) +} + +func (c *Conn) writeFin() { + if c.wroteFin { + return + } + c.write(stFin, c.send_id, nil, c.seq_nr) + c.wroteFin = true + c.event.Broadcast() + return +} + +func (c *Conn) destroy(reason error) { + if c.closed { + return + } + c.closed = true + c.event.Broadcast() + c.err = reason +} + +func (c *Conn) Close() (err error) { + c.mu.Lock() + defer c.mu.Unlock() + c.closing = true + c.event.Broadcast() + c.writeFin() + for { + if c.wroteFin && len(c.unackedSends) <= 1 { + // Sent FIN and it's the only thing unacked. + break + } + if c.closed { + err = c.err + break + } + c.event.Wait() + } + return +} + +func (c *Conn) LocalAddr() net.Addr { + return c.socket.Addr() +} + +func (c *Conn) Read(b []byte) (n int, err error) { + c.mu.Lock() + defer c.mu.Unlock() + for { + if len(c.readBuf) != 0 { + break + } + if c.gotFin { + err = io.EOF + return + } + if c.closed { + if c.err == nil { + panic("closed without receiving fin, and no error") + } + err = c.err + return + } + if c.connDeadlines.read.deadlineExceeded() { + err = errTimeout + return + } + c.event.Wait() + } + n = copy(b, c.readBuf) + c.readBuf = c.readBuf[n:] + + return +} + +func (c *Conn) RemoteAddr() net.Addr { + return c.remoteAddr +} + +func (c *Conn) String() string { + return fmt.Sprintf("", c.LocalAddr(), c.RemoteAddr(), c.recv_id) +} + +func (c *Conn) Write(p []byte) (n int, err error) { + c.mu.Lock() + defer c.mu.Unlock() + for len(p) != 0 { + for { + if c.wroteFin || c.gotFin { + err = io.ErrClosedPipe + return + } + if c.connDeadlines.write.deadlineExceeded() { + err = errTimeout + return + } + // If peerWndSize is 0, we still want to send something, so don't + // block until we exceed it. + if c.synAcked && + len(c.unackedSends) < maxUnackedSends && + c.cur_window <= c.peerWndSize { + break + } + c.event.Wait() + } + var n1 int + n1 = c.write(stData, c.send_id, p, c.seq_nr) + // c.seq_nr++ + n += n1 + p = p[n1:] + } + return +} diff --git a/vendor/QmVBEPpwYNGb5xQW6jPzYgV86KSPRrzhe4hA7o7mtAHZsT/go-utp/utp_test.go b/vendor/QmVBEPpwYNGb5xQW6jPzYgV86KSPRrzhe4hA7o7mtAHZsT/go-utp/utp_test.go new file mode 100644 index 0000000000000000000000000000000000000000..00d5aa35e50714a5e08b4b5551797230e420371f --- /dev/null +++ b/vendor/QmVBEPpwYNGb5xQW6jPzYgV86KSPRrzhe4hA7o7mtAHZsT/go-utp/utp_test.go @@ -0,0 +1,484 @@ +package utp + +import ( + "fmt" + "io" + "io/ioutil" + "log" + "net" + "runtime" + "sync" + "testing" + "time" + + _ "QmWsa476RGjb9scWzcRVts3QZsYjU5Kt6Y9qe8Q3vc5FHR/envpprof" + "github.com/anacrolix/missinggo" + "github.com/bradfitz/iter" + "github.com/stretchr/testify/require" +) + +func init() { + log.SetFlags(log.Flags() | log.Lshortfile) + writeTimeout = 1 * time.Second + initialLatency = 10 * time.Millisecond + packetReadTimeout = 2 * time.Second +} + +func TestUTPPingPong(t *testing.T) { + defer goroutineLeakCheck(t)() + s, err := NewSocket("udp", "localhost:0") + require.NoError(t, err) + defer s.Close() + pingerClosed := make(chan struct{}) + go func() { + defer close(pingerClosed) + b, err := Dial(s.Addr().String()) + require.NoError(t, err) + defer b.Close() + n, err := b.Write([]byte("ping")) + require.NoError(t, err) + require.EqualValues(t, 4, n) + buf := make([]byte, 4) + b.Read(buf) + require.EqualValues(t, "pong", buf) + log.Printf("got pong") + }() + a, err := s.Accept() + require.NoError(t, err) + defer a.Close() + log.Printf("accepted %s", a) + buf := make([]byte, 42) + n, err := a.Read(buf) + require.NoError(t, err) + require.EqualValues(t, "ping", buf[:n]) + log.Print("got ping") + n, err = a.Write([]byte("pong")) + require.NoError(t, err) + require.Equal(t, 4, n) + log.Print("waiting for pinger to close") + <-pingerClosed +} + +func goroutineLeakCheck(t testing.TB) func() { + if !testing.Verbose() { + return func() {} + } + numStart := runtime.NumGoroutine() + return func() { + var numNow int + for range iter.N(1) { + numNow = runtime.NumGoroutine() + if numNow == numStart { + return + } + time.Sleep(10 * time.Millisecond) + } + // I'd print stacks, or treat this as fatal, but I think + // runtime.NumGoroutine is including system routines for which we are + // not provided the stacks, and are spawned unpredictably. + t.Logf("have %d goroutines, started with %d", numNow, numStart) + } +} + +func TestDialTimeout(t *testing.T) { + defer goroutineLeakCheck(t)() + s, _ := NewSocket("udp", "localhost:0") + defer s.Close() + conn, err := DialTimeout(s.Addr().String(), 10*time.Millisecond) + if err == nil { + conn.Close() + t.Fatal("expected timeout") + } + t.Log(err) +} + +func TestMinMaxHeaderType(t *testing.T) { + require.Equal(t, stSyn, stMax) +} + +func TestUTPRawConn(t *testing.T) { + l, err := NewSocket("udp", "") + require.NoError(t, err) + defer l.Close() + go func() { + for { + _, err := l.Accept() + if err != nil { + break + } + } + }() + // Connect a UTP peer to see if the RawConn will still work. + log.Print("dialing") + utpPeer := func() net.Conn { + s, _ := NewSocket("udp", "") + defer s.Close() + ret, err := s.Dial(fmt.Sprintf("localhost:%d", missinggo.AddrPort(l.Addr()))) + require.NoError(t, err) + return ret + }() + log.Print("dial returned") + if err != nil { + t.Fatalf("error dialing utp listener: %s", err) + } + defer utpPeer.Close() + peer, err := net.ListenPacket("udp", ":0") + if err != nil { + t.Fatal(err) + } + defer peer.Close() + + msgsReceived := 0 + const N = 5000 // How many messages to send. + readerStopped := make(chan struct{}) + // The reader goroutine. + go func() { + defer close(readerStopped) + b := make([]byte, 500) + for i := 0; i < N; i++ { + n, _, err := l.ReadFrom(b) + if err != nil { + t.Fatalf("error reading from raw conn: %s", err) + } + msgsReceived++ + var d int + fmt.Sscan(string(b[:n]), &d) + if d != i { + log.Printf("got wrong number: expected %d, got %d", i, d) + } + } + }() + udpAddr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("localhost:%d", missinggo.AddrPort(l.Addr()))) + if err != nil { + t.Fatal(err) + } + for i := 0; i < N; i++ { + _, err := peer.WriteTo([]byte(fmt.Sprintf("%d", i)), udpAddr) + if err != nil { + t.Fatal(err) + } + time.Sleep(10 * time.Microsecond) + } + select { + case <-readerStopped: + case <-time.After(time.Second): + t.Fatal("reader timed out") + } + if msgsReceived != N { + t.Fatalf("messages received: %d", msgsReceived) + } +} + +func TestConnReadDeadline(t *testing.T) { + t.Parallel() + ls, _ := NewSocket("udp", "localhost:0") + ds, _ := NewSocket("udp", "localhost:0") + dcReadErr := make(chan error) + go func() { + c, _ := ds.Dial(ls.Addr().String()) + defer c.Close() + _, err := c.Read(nil) + dcReadErr <- err + }() + c, _ := ls.Accept() + dl := time.Now().Add(time.Millisecond) + c.SetReadDeadline(dl) + _, err := c.Read(nil) + require.Equal(t, errTimeout, err) + // The deadline has passed. + if !time.Now().After(dl) { + t.FailNow() + } + // Returns timeout on subsequent read. + _, err = c.Read(nil) + require.Equal(t, errTimeout, err) + // Disable the deadline. + c.SetReadDeadline(time.Time{}) + readReturned := make(chan struct{}) + go func() { + c.Read(nil) + close(readReturned) + }() + select { + case <-readReturned: + // Read returned but shouldn't have. + t.FailNow() + case <-time.After(time.Millisecond): + } + c.Close() + if err := <-dcReadErr; err != io.EOF { + t.Fatalf("dial conn read returned %s", err) + } + select { + case <-readReturned: + case <-time.After(time.Millisecond): + t.Fatal("read should return after Conn is closed") + } +} + +func connectSelfLots(n int, t testing.TB) { + defer goroutineLeakCheck(t)() + s, err := NewSocket("udp", "localhost:0") + if err != nil { + t.Fatal(err) + } + go func() { + for range iter.N(n) { + c, err := s.Accept() + if err != nil { + log.Fatal(err) + } + defer c.Close() + } + }() + dialErr := make(chan error) + connCh := make(chan net.Conn) + dialSema := make(chan struct{}, backlog) + for range iter.N(n) { + go func() { + dialSema <- struct{}{} + c, err := s.Dial(s.Addr().String()) + <-dialSema + if err != nil { + dialErr <- err + return + } + connCh <- c + }() + } + conns := make([]net.Conn, 0, n) + for range iter.N(n) { + select { + case c := <-connCh: + conns = append(conns, c) + case err := <-dialErr: + t.Fatal(err) + } + } + for _, c := range conns { + if c != nil { + c.Close() + } + } + s.mu.Lock() + for len(s.conns) != 0 { + // log.Print(len(s.conns)) + s.event.Wait() + } + s.mu.Unlock() + s.Close() +} + +// Connect to ourself heaps. +func TestConnectSelf(t *testing.T) { + t.Parallel() + // A rough guess says that at worst, I can only have 0x10000/3 connections + // to the same socket, due to fragmentation in the assigned connection + // IDs. + connectSelfLots(0x1000, t) +} + +func BenchmarkConnectSelf(b *testing.B) { + for range iter.N(b.N) { + connectSelfLots(2, b) + } +} + +func BenchmarkNewCloseSocket(b *testing.B) { + for range iter.N(b.N) { + s, err := NewSocket("udp", "localhost:0") + if err != nil { + b.Fatal(err) + } + err = s.Close() + if err != nil { + b.Fatal(err) + } + } +} + +func TestRejectDialBacklogFilled(t *testing.T) { + s, err := NewSocket("udp", "localhost:0") + if err != nil { + t.Fatal(err) + } + errChan := make(chan error, 1) + dial := func() { + _, err := s.Dial(s.Addr().String()) + if err != nil { + errChan <- err + } + } + // Fill the backlog. + for range iter.N(backlog + 1) { + go dial() + } + s.mu.Lock() + for len(s.backlog) < backlog { + s.event.Wait() + } + s.mu.Unlock() + select { + case <-errChan: + t.FailNow() + default: + } + // One more connection should cause a dial attempt to get reset. + go dial() + err = <-errChan + if err.Error() != "peer reset" { + t.FailNow() + } + s.Close() +} + +// Make sure that we can reset AfterFunc timers, so we don't have to create +// brand new ones everytime they fire. Specifically for the Conn resend timer. +func TestResetAfterFuncTimer(t *testing.T) { + t.Parallel() + fired := make(chan struct{}) + timer := time.AfterFunc(time.Millisecond, func() { + fired <- struct{}{} + }) + <-fired + if timer.Reset(time.Millisecond) { + // The timer should have expired + t.FailNow() + } + <-fired +} + +func connPair() (initer, accepted net.Conn) { + s, err := NewSocket("udp", "localhost:0") + if err != nil { + panic(err) + } + defer s.Close() + var wg sync.WaitGroup + wg.Add(1) + go func() { + defer wg.Done() + var err error + initer, err = Dial(s.Addr().String()) + if err != nil { + panic(err) + } + }() + accepted, err = s.Accept() + if err != nil { + panic(err) + } + wg.Wait() + return +} + +// Check that peer sending FIN doesn't cause unread data to be dropped in a +// receiver. +func TestReadFinishedConn(t *testing.T) { + a, b := connPair() + defer a.Close() + defer b.Close() + mu.Lock() + originalAPDC := artificialPacketDropChance + artificialPacketDropChance = 1 + mu.Unlock() + n, err := a.Write([]byte("hello")) + require.Equal(t, 5, n) + require.NoError(t, err) + n, err = a.Write([]byte("world")) + require.Equal(t, 5, n) + require.NoError(t, err) + mu.Lock() + artificialPacketDropChance = originalAPDC + mu.Unlock() + a.Close() + all, err := ioutil.ReadAll(b) + require.NoError(t, err) + require.EqualValues(t, "helloworld", all) +} + +func TestCloseDetachesQuickly(t *testing.T) { + t.Parallel() + s, _ := NewSocket("udp", "localhost:0") + defer s.Close() + go func() { + a, _ := s.Dial(s.Addr().String()) + log.Print("close a") + a.Close() + log.Print("closed a") + }() + b, _ := s.Accept() + b.Close() + s.mu.Lock() + for len(s.conns) != 0 { + log.Print(len(s.conns)) + s.event.Wait() + } + s.mu.Unlock() +} + +// Check that closing, and resulting detach of a Conn doesn't close the parent +// Socket. We Accept, then close the connection and ensure it's detached. Then +// Accept again to check the Socket is still functional and unclosed. +func TestConnCloseUnclosedSocket(t *testing.T) { + t.Parallel() + s, err := NewSocket("udp", "localhost:0") + require.NoError(t, err) + defer func() { + require.NoError(t, s.Close()) + }() + // Prevents the dialing goroutine from closing its end of the Conn before + // we can check that it has been registered in the listener. + dialerSync := make(chan struct{}) + + go func() { + for range iter.N(2) { + c, err := Dial(s.Addr().String()) + require.NoError(t, err) + <-dialerSync + err = c.Close() + require.NoError(t, err) + } + }() + for range iter.N(2) { + a, err := s.Accept() + require.NoError(t, err) + // We do this in a closure because we need to unlock Server.mu if the + // test failure exception is thrown. "Do as we say, not as we do" -Go + // team. + func() { + s.mu.Lock() + defer s.mu.Unlock() + require.Len(t, s.conns, 1) + }() + dialerSync <- struct{}{} + require.NoError(t, a.Close()) + func() { + s.mu.Lock() + defer s.mu.Unlock() + for len(s.conns) != 0 { + s.event.Wait() + } + }() + } +} + +func TestAcceptGone(t *testing.T) { + s, _ := NewSocket("udp", "localhost:0") + _, err := DialTimeout(s.Addr().String(), time.Millisecond) + require.Error(t, err) + c, _ := s.Accept() + c.SetReadDeadline(time.Now().Add(time.Millisecond)) + c.Read(nil) + // select {} +} + +func TestPacketReadTimeout(t *testing.T) { + t.Parallel() + a, b := connPair() + _, err := a.Read(nil) + require.Contains(t, err.Error(), "timeout") + t.Log(err) + t.Log(a.Close()) + t.Log(b.Close()) +} diff --git a/vendor/QmVdADza4QFVAR9xqAxRQjt9vTZJ6UrVLgBstKua1Xg7he/multiaddr-filter/LICENSE b/vendor/QmVdADza4QFVAR9xqAxRQjt9vTZJ6UrVLgBstKua1Xg7he/multiaddr-filter/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..1a976e72e7d626d74ed9310e54a4b537d2e8012a --- /dev/null +++ b/vendor/QmVdADza4QFVAR9xqAxRQjt9vTZJ6UrVLgBstKua1Xg7he/multiaddr-filter/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Jeromy Johnson + +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. + +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. diff --git a/vendor/QmVdADza4QFVAR9xqAxRQjt9vTZJ6UrVLgBstKua1Xg7he/multiaddr-filter/README.md b/vendor/QmVdADza4QFVAR9xqAxRQjt9vTZJ6UrVLgBstKua1Xg7he/multiaddr-filter/README.md new file mode 100644 index 0000000000000000000000000000000000000000..6a3ca8f8382a0879de1f0496e975c2e345209f4c --- /dev/null +++ b/vendor/QmVdADza4QFVAR9xqAxRQjt9vTZJ6UrVLgBstKua1Xg7he/multiaddr-filter/README.md @@ -0,0 +1,15 @@ +# go-multiaddr-filter -- CIDR netmasks with multiaddr + +This module creates very simple [multiaddr](https://github.com/jbenet/go-multiaddr) formatted cidr netmasks. + +It doesn't do full multiaddr parsing to save on vendoring things and perf. The `net` package will take care of verifying the validity of the network part anyway. + +## Usage + +```go + +import filter "github.com/whyrusleeping/multiaddr-filter" + +filter.NewMask("/ip4/192.168.0.0/24") // ipv4 +filter.NewMask("/ip6/fe80::/64") // ipv6 +``` diff --git a/vendor/QmVdADza4QFVAR9xqAxRQjt9vTZJ6UrVLgBstKua1Xg7he/multiaddr-filter/mask.go b/vendor/QmVdADza4QFVAR9xqAxRQjt9vTZJ6UrVLgBstKua1Xg7he/multiaddr-filter/mask.go new file mode 100644 index 0000000000000000000000000000000000000000..7a724d115d2580a35cfd0084aea19da8c99d398d --- /dev/null +++ b/vendor/QmVdADza4QFVAR9xqAxRQjt9vTZJ6UrVLgBstKua1Xg7he/multiaddr-filter/mask.go @@ -0,0 +1,47 @@ +package mask + +import ( + "errors" + "fmt" + "net" + "strings" + + manet "QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net" +) + +var ErrInvalidFormat = errors.New("invalid multiaddr-filter format") + +func NewMask(a string) (*net.IPNet, error) { + parts := strings.Split(a, "/") + + if parts[0] != "" { + return nil, ErrInvalidFormat + } + + if len(parts) != 5 { + return nil, ErrInvalidFormat + } + + // check it's a valid filter address. ip + cidr + isip := parts[1] == "ip4" || parts[1] == "ip6" + iscidr := parts[3] == "ipcidr" + if !isip || !iscidr { + return nil, ErrInvalidFormat + } + + _, ipn, err := net.ParseCIDR(parts[2] + "/" + parts[4]) + if err != nil { + return nil, err + } + return ipn, nil +} + +func ConvertIPNet(n *net.IPNet) (string, error) { + addr, err := manet.FromIP(n.IP) + if err != nil { + return "", err + } + + b, _ := n.Mask.Size() + return fmt.Sprintf("%s/ipcidr/%d", addr, b), nil +} diff --git a/vendor/QmVdADza4QFVAR9xqAxRQjt9vTZJ6UrVLgBstKua1Xg7he/multiaddr-filter/mask_test.go b/vendor/QmVdADza4QFVAR9xqAxRQjt9vTZJ6UrVLgBstKua1Xg7he/multiaddr-filter/mask_test.go new file mode 100644 index 0000000000000000000000000000000000000000..2dcc016b14e822490d06fe4140201322f2963255 --- /dev/null +++ b/vendor/QmVdADza4QFVAR9xqAxRQjt9vTZJ6UrVLgBstKua1Xg7he/multiaddr-filter/mask_test.go @@ -0,0 +1,132 @@ +package mask + +import ( + "net" + "testing" +) + +func TestValidMasks(t *testing.T) { + + cidrOrFatal := func(s string) *net.IPNet { + _, ipn, err := net.ParseCIDR(s) + if err != nil { + t.Fatal(err) + } + return ipn + } + + testCases := map[string]*net.IPNet{ + "/ip4/1.2.3.4/ipcidr/0": cidrOrFatal("1.2.3.4/0"), + "/ip4/1.2.3.4/ipcidr/32": cidrOrFatal("1.2.3.4/32"), + "/ip4/1.2.3.4/ipcidr/24": cidrOrFatal("1.2.3.4/24"), + "/ip4/192.168.0.0/ipcidr/28": cidrOrFatal("192.168.0.0/28"), + "/ip6/fe80::/ipcidr/0": cidrOrFatal("fe80::/0"), + "/ip6/fe80::/ipcidr/64": cidrOrFatal("fe80::/64"), + "/ip6/fe80::/ipcidr/128": cidrOrFatal("fe80::/128"), + } + + for s, m1 := range testCases { + m2, err := NewMask(s) + if err != nil { + t.Error("should be invalid:", s) + continue + } + + if m1.String() != m2.String() { + t.Error("masks not equal:", m1, m2) + } + } + +} + +func TestInvalidMasks(t *testing.T) { + + testCases := []string{ + "/", + "/ip4/10.1.2.3", + "/ip6/::", + "/ip4/1.2.3.4/cidr/24", + "/ip6/fe80::/cidr/24", + "/eth/aa:aa:aa:aa:aa/ipcidr/24", + "foobar/ip4/1.2.3.4/ipcidr/32", + } + + for _, s := range testCases { + _, err := NewMask(s) + if err != ErrInvalidFormat { + t.Error("should be invalid:", s) + } + } + + testCases2 := []string{ + "/ip4/1.2.3.4/ipcidr/33", + "/ip4/192.168.0.0/ipcidr/-1", + "/ip6/fe80::/ipcidr/129", + } + + for _, s := range testCases2 { + _, err := NewMask(s) + if err == nil { + t.Error("should be invalid:", s) + } + } + +} + +func TestFiltered(t *testing.T) { + var tests = map[string]map[string]bool{ + "/ip4/10.0.0.0/ipcidr/8": map[string]bool{ + "10.3.3.4": true, + "10.3.4.4": true, + "10.4.4.4": true, + "15.52.34.3": false, + }, + "/ip4/192.168.0.0/ipcidr/16": map[string]bool{ + "192.168.0.0": true, + "192.168.1.0": true, + "192.1.0.0": false, + "10.4.4.4": false, + }, + } + + for mask, set := range tests { + m, err := NewMask(mask) + if err != nil { + t.Fatal(err) + } + for addr, val := range set { + ip := net.ParseIP(addr) + if m.Contains(ip) != val { + t.Fatalf("expected contains(%s, %s) == %s", mask, addr, val) + } + } + } +} + +func TestParsing(t *testing.T) { + var addrs = map[string]string{ + "/ip4/192.168.0.0/ipcidr/16": "192.168.0.0/16", + "/ip4/192.0.0.0/ipcidr/8": "192.0.0.0/8", + "/ip6/2001:db8::/ipcidr/32": "2001:db8::/32", + } + + for k, v := range addrs { + m, err := NewMask(k) + if err != nil { + t.Fatal(err) + } + + if m.String() != v { + t.Fatalf("mask is wrong: ", m, v) + } + + orig, err := ConvertIPNet(m) + if err != nil { + t.Fatal(err) + } + + if orig != k { + t.Fatal("backwards conversion failed: ", orig, k) + } + } +} diff --git a/vendor/QmVdADza4QFVAR9xqAxRQjt9vTZJ6UrVLgBstKua1Xg7he/multiaddr-filter/package.json b/vendor/QmVdADza4QFVAR9xqAxRQjt9vTZJ6UrVLgBstKua1Xg7he/multiaddr-filter/package.json new file mode 100644 index 0000000000000000000000000000000000000000..b203d159e22fbce81b9fbb58038faebceca5f34f --- /dev/null +++ b/vendor/QmVdADza4QFVAR9xqAxRQjt9vTZJ6UrVLgBstKua1Xg7he/multiaddr-filter/package.json @@ -0,0 +1,16 @@ +{ + "name": "multiaddr-filter", + "author": "whyrusleeping", + "version": "1.0.0", + "gxDependencies": [ + { + "name": "go-multiaddr-net", + "hash": "QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr", + "version": "1.0.0" + } + ], + "language": "go", + "gx": { + "dvcsimport": "github.com/whyrusleeping/multiaddr-filter" + } +} \ No newline at end of file diff --git a/vendor/QmWsa476RGjb9scWzcRVts3QZsYjU5Kt6Y9qe8Q3vc5FHR/envpprof/envpprof.go b/vendor/QmWsa476RGjb9scWzcRVts3QZsYjU5Kt6Y9qe8Q3vc5FHR/envpprof/envpprof.go new file mode 100644 index 0000000000000000000000000000000000000000..8fe356ca6fd48e4cb41c1b68480e243ee3c66aac --- /dev/null +++ b/vendor/QmWsa476RGjb9scWzcRVts3QZsYjU5Kt6Y9qe8Q3vc5FHR/envpprof/envpprof.go @@ -0,0 +1,92 @@ +package envpprof + +import ( + "fmt" + "io/ioutil" + "log" + "net" + "net/http" + _ "net/http/pprof" + "os" + "path/filepath" + "runtime" + "runtime/pprof" + "strings" +) + +var ( + pprofDir = filepath.Join(os.Getenv("HOME"), "pprof") + heap bool +) + +func writeHeapProfile() { + os.Mkdir(pprofDir, 0750) + f, err := ioutil.TempFile(pprofDir, "heap") + if err != nil { + log.Printf("error creating heap profile file: %s", err) + return + } + defer f.Close() + pprof.WriteHeapProfile(f) + log.Printf("wrote heap profile to %q", f.Name()) +} + +func Stop() { + pprof.StopCPUProfile() + if heap { + writeHeapProfile() + } +} + +func init() { + for _, item := range strings.Split(os.Getenv("GOPPROF"), ",") { + equalsPos := strings.IndexByte(item, '=') + var key, value string + if equalsPos < 0 { + key = item + } else { + key = item[:equalsPos] + value = item[equalsPos+1:] + } + if value != "" { + log.Printf("values not yet supported") + } + switch key { + case "http": + go func() { + var l net.Listener + for port := uint16(6061); port != 6060; port++ { + var err error + l, err = net.Listen("tcp", fmt.Sprintf("localhost:%d", port)) + if err == nil { + break + } + } + if l == nil { + log.Print("unable to create envpprof listener for http") + return + } + defer l.Close() + log.Printf("envpprof serving http://%s", l.Addr()) + log.Printf("error serving http on envpprof listener: %s", http.Serve(l, nil)) + }() + case "cpu": + os.Mkdir(pprofDir, 0750) + f, err := ioutil.TempFile(pprofDir, "cpu") + if err != nil { + log.Printf("error creating cpu pprof file: %s", err) + break + } + err = pprof.StartCPUProfile(f) + if err != nil { + log.Printf("error starting cpu profiling: %s", err) + break + } + log.Printf("cpu profiling to file %q", f.Name()) + case "block": + runtime.SetBlockProfileRate(1) + case "heap": + heap = true + } + } +} diff --git a/vendor/QmWsa476RGjb9scWzcRVts3QZsYjU5Kt6Y9qe8Q3vc5FHR/envpprof/package.json b/vendor/QmWsa476RGjb9scWzcRVts3QZsYjU5Kt6Y9qe8Q3vc5FHR/envpprof/package.json new file mode 100644 index 0000000000000000000000000000000000000000..9eb05e9d1986978fbd14eedd23ffc760b85174c0 --- /dev/null +++ b/vendor/QmWsa476RGjb9scWzcRVts3QZsYjU5Kt6Y9qe8Q3vc5FHR/envpprof/package.json @@ -0,0 +1,9 @@ +{ + "name": "envpprof", + "author": "whyrusleeping", + "version": "1.0.0", + "language": "go", + "gx": { + "dvcsimport": "github.com/anacrolix/envpprof" + } +} \ No newline at end of file diff --git a/vendor/QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb/crypto-sha3/doc.go b/vendor/QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb/crypto-sha3/doc.go new file mode 100644 index 0000000000000000000000000000000000000000..a0ee3ae725d032acefd5950481a1fe70d84f2d4b --- /dev/null +++ b/vendor/QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb/crypto-sha3/doc.go @@ -0,0 +1,66 @@ +// Copyright 2014 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 sha3 implements the SHA-3 fixed-output-length hash functions and +// the SHAKE variable-output-length hash functions defined by FIPS-202. +// +// Both types of hash function use the "sponge" construction and the Keccak +// permutation. For a detailed specification see http://keccak.noekeon.org/ +// +// +// Guidance +// +// If you aren't sure what function you need, use SHAKE256 with at least 64 +// bytes of output. The SHAKE instances are faster than the SHA3 instances; +// the latter have to allocate memory to conform to the hash.Hash interface. +// +// If you need a secret-key MAC (message authentication code), prepend the +// secret key to the input, hash with SHAKE256 and read at least 32 bytes of +// output. +// +// +// Security strengths +// +// The SHA3-x (x equals 224, 256, 384, or 512) functions have a security +// strength against preimage attacks of x bits. Since they only produce "x" +// bits of output, their collision-resistance is only "x/2" bits. +// +// The SHAKE-256 and -128 functions have a generic security strength of 256 and +// 128 bits against all attacks, provided that at least 2x bits of their output +// is used. Requesting more than 64 or 32 bytes of output, respectively, does +// not increase the collision-resistance of the SHAKE functions. +// +// +// The sponge construction +// +// A sponge builds a pseudo-random function from a public pseudo-random +// permutation, by applying the permutation to a state of "rate + capacity" +// bytes, but hiding "capacity" of the bytes. +// +// A sponge starts out with a zero state. To hash an input using a sponge, up +// to "rate" bytes of the input are XORed into the sponge's state. The sponge +// is then "full" and the permutation is applied to "empty" it. This process is +// repeated until all the input has been "absorbed". The input is then padded. +// The digest is "squeezed" from the sponge in the same way, except that output +// output is copied out instead of input being XORed in. +// +// A sponge is parameterized by its generic security strength, which is equal +// to half its capacity; capacity + rate is equal to the permutation's width. +// Since the KeccakF-1600 permutation is 1600 bits (200 bytes) wide, this means +// that the security strength of a sponge instance is equal to (1600 - bitrate) / 2. +// +// +// Recommendations +// +// The SHAKE functions are recommended for most new uses. They can produce +// output of arbitrary length. SHAKE256, with an output length of at least +// 64 bytes, provides 256-bit security against all attacks. The Keccak team +// recommends it for most applications upgrading from SHA2-512. (NIST chose a +// much stronger, but much slower, sponge instance for SHA3-512.) +// +// The SHA-3 functions are "drop-in" replacements for the SHA-2 functions. +// They produce output of the same length, with the same security strengths +// against all attacks. This means, in particular, that SHA3-256 only has +// 128-bit collision resistance, because its output length is 32 bytes. +package sha3 // import "golang.org/x/crypto/sha3" diff --git a/vendor/QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb/crypto-sha3/hashes.go b/vendor/QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb/crypto-sha3/hashes.go new file mode 100644 index 0000000000000000000000000000000000000000..2b51cf4e9b4047eb4d89cd96780b714bddd91677 --- /dev/null +++ b/vendor/QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb/crypto-sha3/hashes.go @@ -0,0 +1,65 @@ +// Copyright 2014 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 sha3 + +// This file provides functions for creating instances of the SHA-3 +// and SHAKE hash functions, as well as utility functions for hashing +// bytes. + +import ( + "hash" +) + +// New224 creates a new SHA3-224 hash. +// Its generic security strength is 224 bits against preimage attacks, +// and 112 bits against collision attacks. +func New224() hash.Hash { return &state{rate: 144, outputLen: 28, dsbyte: 0x06} } + +// New256 creates a new SHA3-256 hash. +// Its generic security strength is 256 bits against preimage attacks, +// and 128 bits against collision attacks. +func New256() hash.Hash { return &state{rate: 136, outputLen: 32, dsbyte: 0x06} } + +// New384 creates a new SHA3-384 hash. +// Its generic security strength is 384 bits against preimage attacks, +// and 192 bits against collision attacks. +func New384() hash.Hash { return &state{rate: 104, outputLen: 48, dsbyte: 0x06} } + +// New512 creates a new SHA3-512 hash. +// Its generic security strength is 512 bits against preimage attacks, +// and 256 bits against collision attacks. +func New512() hash.Hash { return &state{rate: 72, outputLen: 64, dsbyte: 0x06} } + +// Sum224 returns the SHA3-224 digest of the data. +func Sum224(data []byte) (digest [28]byte) { + h := New224() + h.Write(data) + h.Sum(digest[:0]) + return +} + +// Sum256 returns the SHA3-256 digest of the data. +func Sum256(data []byte) (digest [32]byte) { + h := New256() + h.Write(data) + h.Sum(digest[:0]) + return +} + +// Sum384 returns the SHA3-384 digest of the data. +func Sum384(data []byte) (digest [48]byte) { + h := New384() + h.Write(data) + h.Sum(digest[:0]) + return +} + +// Sum512 returns the SHA3-512 digest of the data. +func Sum512(data []byte) (digest [64]byte) { + h := New512() + h.Write(data) + h.Sum(digest[:0]) + return +} diff --git a/vendor/QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb/crypto-sha3/keccakf.go b/vendor/QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb/crypto-sha3/keccakf.go new file mode 100644 index 0000000000000000000000000000000000000000..13e7058fa9861b05e453217a1af61bbfabd45f5c --- /dev/null +++ b/vendor/QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb/crypto-sha3/keccakf.go @@ -0,0 +1,410 @@ +// Copyright 2014 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 sha3 + +// rc stores the round constants for use in the ι step. +var rc = [24]uint64{ + 0x0000000000000001, + 0x0000000000008082, + 0x800000000000808A, + 0x8000000080008000, + 0x000000000000808B, + 0x0000000080000001, + 0x8000000080008081, + 0x8000000000008009, + 0x000000000000008A, + 0x0000000000000088, + 0x0000000080008009, + 0x000000008000000A, + 0x000000008000808B, + 0x800000000000008B, + 0x8000000000008089, + 0x8000000000008003, + 0x8000000000008002, + 0x8000000000000080, + 0x000000000000800A, + 0x800000008000000A, + 0x8000000080008081, + 0x8000000000008080, + 0x0000000080000001, + 0x8000000080008008, +} + +// keccakF1600 applies the Keccak permutation to a 1600b-wide +// state represented as a slice of 25 uint64s. +func keccakF1600(a *[25]uint64) { + // Implementation translated from Keccak-inplace.c + // in the keccak reference code. + var t, bc0, bc1, bc2, bc3, bc4, d0, d1, d2, d3, d4 uint64 + + for i := 0; i < 24; i += 4 { + // Combines the 5 steps in each round into 2 steps. + // Unrolls 4 rounds per loop and spreads some steps across rounds. + + // Round 1 + bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20] + bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21] + bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22] + bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23] + bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24] + d0 = bc4 ^ (bc1<<1 | bc1>>63) + d1 = bc0 ^ (bc2<<1 | bc2>>63) + d2 = bc1 ^ (bc3<<1 | bc3>>63) + d3 = bc2 ^ (bc4<<1 | bc4>>63) + d4 = bc3 ^ (bc0<<1 | bc0>>63) + + bc0 = a[0] ^ d0 + t = a[6] ^ d1 + bc1 = t<<44 | t>>(64-44) + t = a[12] ^ d2 + bc2 = t<<43 | t>>(64-43) + t = a[18] ^ d3 + bc3 = t<<21 | t>>(64-21) + t = a[24] ^ d4 + bc4 = t<<14 | t>>(64-14) + a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i] + a[6] = bc1 ^ (bc3 &^ bc2) + a[12] = bc2 ^ (bc4 &^ bc3) + a[18] = bc3 ^ (bc0 &^ bc4) + a[24] = bc4 ^ (bc1 &^ bc0) + + t = a[10] ^ d0 + bc2 = t<<3 | t>>(64-3) + t = a[16] ^ d1 + bc3 = t<<45 | t>>(64-45) + t = a[22] ^ d2 + bc4 = t<<61 | t>>(64-61) + t = a[3] ^ d3 + bc0 = t<<28 | t>>(64-28) + t = a[9] ^ d4 + bc1 = t<<20 | t>>(64-20) + a[10] = bc0 ^ (bc2 &^ bc1) + a[16] = bc1 ^ (bc3 &^ bc2) + a[22] = bc2 ^ (bc4 &^ bc3) + a[3] = bc3 ^ (bc0 &^ bc4) + a[9] = bc4 ^ (bc1 &^ bc0) + + t = a[20] ^ d0 + bc4 = t<<18 | t>>(64-18) + t = a[1] ^ d1 + bc0 = t<<1 | t>>(64-1) + t = a[7] ^ d2 + bc1 = t<<6 | t>>(64-6) + t = a[13] ^ d3 + bc2 = t<<25 | t>>(64-25) + t = a[19] ^ d4 + bc3 = t<<8 | t>>(64-8) + a[20] = bc0 ^ (bc2 &^ bc1) + a[1] = bc1 ^ (bc3 &^ bc2) + a[7] = bc2 ^ (bc4 &^ bc3) + a[13] = bc3 ^ (bc0 &^ bc4) + a[19] = bc4 ^ (bc1 &^ bc0) + + t = a[5] ^ d0 + bc1 = t<<36 | t>>(64-36) + t = a[11] ^ d1 + bc2 = t<<10 | t>>(64-10) + t = a[17] ^ d2 + bc3 = t<<15 | t>>(64-15) + t = a[23] ^ d3 + bc4 = t<<56 | t>>(64-56) + t = a[4] ^ d4 + bc0 = t<<27 | t>>(64-27) + a[5] = bc0 ^ (bc2 &^ bc1) + a[11] = bc1 ^ (bc3 &^ bc2) + a[17] = bc2 ^ (bc4 &^ bc3) + a[23] = bc3 ^ (bc0 &^ bc4) + a[4] = bc4 ^ (bc1 &^ bc0) + + t = a[15] ^ d0 + bc3 = t<<41 | t>>(64-41) + t = a[21] ^ d1 + bc4 = t<<2 | t>>(64-2) + t = a[2] ^ d2 + bc0 = t<<62 | t>>(64-62) + t = a[8] ^ d3 + bc1 = t<<55 | t>>(64-55) + t = a[14] ^ d4 + bc2 = t<<39 | t>>(64-39) + a[15] = bc0 ^ (bc2 &^ bc1) + a[21] = bc1 ^ (bc3 &^ bc2) + a[2] = bc2 ^ (bc4 &^ bc3) + a[8] = bc3 ^ (bc0 &^ bc4) + a[14] = bc4 ^ (bc1 &^ bc0) + + // Round 2 + bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20] + bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21] + bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22] + bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23] + bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24] + d0 = bc4 ^ (bc1<<1 | bc1>>63) + d1 = bc0 ^ (bc2<<1 | bc2>>63) + d2 = bc1 ^ (bc3<<1 | bc3>>63) + d3 = bc2 ^ (bc4<<1 | bc4>>63) + d4 = bc3 ^ (bc0<<1 | bc0>>63) + + bc0 = a[0] ^ d0 + t = a[16] ^ d1 + bc1 = t<<44 | t>>(64-44) + t = a[7] ^ d2 + bc2 = t<<43 | t>>(64-43) + t = a[23] ^ d3 + bc3 = t<<21 | t>>(64-21) + t = a[14] ^ d4 + bc4 = t<<14 | t>>(64-14) + a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i+1] + a[16] = bc1 ^ (bc3 &^ bc2) + a[7] = bc2 ^ (bc4 &^ bc3) + a[23] = bc3 ^ (bc0 &^ bc4) + a[14] = bc4 ^ (bc1 &^ bc0) + + t = a[20] ^ d0 + bc2 = t<<3 | t>>(64-3) + t = a[11] ^ d1 + bc3 = t<<45 | t>>(64-45) + t = a[2] ^ d2 + bc4 = t<<61 | t>>(64-61) + t = a[18] ^ d3 + bc0 = t<<28 | t>>(64-28) + t = a[9] ^ d4 + bc1 = t<<20 | t>>(64-20) + a[20] = bc0 ^ (bc2 &^ bc1) + a[11] = bc1 ^ (bc3 &^ bc2) + a[2] = bc2 ^ (bc4 &^ bc3) + a[18] = bc3 ^ (bc0 &^ bc4) + a[9] = bc4 ^ (bc1 &^ bc0) + + t = a[15] ^ d0 + bc4 = t<<18 | t>>(64-18) + t = a[6] ^ d1 + bc0 = t<<1 | t>>(64-1) + t = a[22] ^ d2 + bc1 = t<<6 | t>>(64-6) + t = a[13] ^ d3 + bc2 = t<<25 | t>>(64-25) + t = a[4] ^ d4 + bc3 = t<<8 | t>>(64-8) + a[15] = bc0 ^ (bc2 &^ bc1) + a[6] = bc1 ^ (bc3 &^ bc2) + a[22] = bc2 ^ (bc4 &^ bc3) + a[13] = bc3 ^ (bc0 &^ bc4) + a[4] = bc4 ^ (bc1 &^ bc0) + + t = a[10] ^ d0 + bc1 = t<<36 | t>>(64-36) + t = a[1] ^ d1 + bc2 = t<<10 | t>>(64-10) + t = a[17] ^ d2 + bc3 = t<<15 | t>>(64-15) + t = a[8] ^ d3 + bc4 = t<<56 | t>>(64-56) + t = a[24] ^ d4 + bc0 = t<<27 | t>>(64-27) + a[10] = bc0 ^ (bc2 &^ bc1) + a[1] = bc1 ^ (bc3 &^ bc2) + a[17] = bc2 ^ (bc4 &^ bc3) + a[8] = bc3 ^ (bc0 &^ bc4) + a[24] = bc4 ^ (bc1 &^ bc0) + + t = a[5] ^ d0 + bc3 = t<<41 | t>>(64-41) + t = a[21] ^ d1 + bc4 = t<<2 | t>>(64-2) + t = a[12] ^ d2 + bc0 = t<<62 | t>>(64-62) + t = a[3] ^ d3 + bc1 = t<<55 | t>>(64-55) + t = a[19] ^ d4 + bc2 = t<<39 | t>>(64-39) + a[5] = bc0 ^ (bc2 &^ bc1) + a[21] = bc1 ^ (bc3 &^ bc2) + a[12] = bc2 ^ (bc4 &^ bc3) + a[3] = bc3 ^ (bc0 &^ bc4) + a[19] = bc4 ^ (bc1 &^ bc0) + + // Round 3 + bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20] + bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21] + bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22] + bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23] + bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24] + d0 = bc4 ^ (bc1<<1 | bc1>>63) + d1 = bc0 ^ (bc2<<1 | bc2>>63) + d2 = bc1 ^ (bc3<<1 | bc3>>63) + d3 = bc2 ^ (bc4<<1 | bc4>>63) + d4 = bc3 ^ (bc0<<1 | bc0>>63) + + bc0 = a[0] ^ d0 + t = a[11] ^ d1 + bc1 = t<<44 | t>>(64-44) + t = a[22] ^ d2 + bc2 = t<<43 | t>>(64-43) + t = a[8] ^ d3 + bc3 = t<<21 | t>>(64-21) + t = a[19] ^ d4 + bc4 = t<<14 | t>>(64-14) + a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i+2] + a[11] = bc1 ^ (bc3 &^ bc2) + a[22] = bc2 ^ (bc4 &^ bc3) + a[8] = bc3 ^ (bc0 &^ bc4) + a[19] = bc4 ^ (bc1 &^ bc0) + + t = a[15] ^ d0 + bc2 = t<<3 | t>>(64-3) + t = a[1] ^ d1 + bc3 = t<<45 | t>>(64-45) + t = a[12] ^ d2 + bc4 = t<<61 | t>>(64-61) + t = a[23] ^ d3 + bc0 = t<<28 | t>>(64-28) + t = a[9] ^ d4 + bc1 = t<<20 | t>>(64-20) + a[15] = bc0 ^ (bc2 &^ bc1) + a[1] = bc1 ^ (bc3 &^ bc2) + a[12] = bc2 ^ (bc4 &^ bc3) + a[23] = bc3 ^ (bc0 &^ bc4) + a[9] = bc4 ^ (bc1 &^ bc0) + + t = a[5] ^ d0 + bc4 = t<<18 | t>>(64-18) + t = a[16] ^ d1 + bc0 = t<<1 | t>>(64-1) + t = a[2] ^ d2 + bc1 = t<<6 | t>>(64-6) + t = a[13] ^ d3 + bc2 = t<<25 | t>>(64-25) + t = a[24] ^ d4 + bc3 = t<<8 | t>>(64-8) + a[5] = bc0 ^ (bc2 &^ bc1) + a[16] = bc1 ^ (bc3 &^ bc2) + a[2] = bc2 ^ (bc4 &^ bc3) + a[13] = bc3 ^ (bc0 &^ bc4) + a[24] = bc4 ^ (bc1 &^ bc0) + + t = a[20] ^ d0 + bc1 = t<<36 | t>>(64-36) + t = a[6] ^ d1 + bc2 = t<<10 | t>>(64-10) + t = a[17] ^ d2 + bc3 = t<<15 | t>>(64-15) + t = a[3] ^ d3 + bc4 = t<<56 | t>>(64-56) + t = a[14] ^ d4 + bc0 = t<<27 | t>>(64-27) + a[20] = bc0 ^ (bc2 &^ bc1) + a[6] = bc1 ^ (bc3 &^ bc2) + a[17] = bc2 ^ (bc4 &^ bc3) + a[3] = bc3 ^ (bc0 &^ bc4) + a[14] = bc4 ^ (bc1 &^ bc0) + + t = a[10] ^ d0 + bc3 = t<<41 | t>>(64-41) + t = a[21] ^ d1 + bc4 = t<<2 | t>>(64-2) + t = a[7] ^ d2 + bc0 = t<<62 | t>>(64-62) + t = a[18] ^ d3 + bc1 = t<<55 | t>>(64-55) + t = a[4] ^ d4 + bc2 = t<<39 | t>>(64-39) + a[10] = bc0 ^ (bc2 &^ bc1) + a[21] = bc1 ^ (bc3 &^ bc2) + a[7] = bc2 ^ (bc4 &^ bc3) + a[18] = bc3 ^ (bc0 &^ bc4) + a[4] = bc4 ^ (bc1 &^ bc0) + + // Round 4 + bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20] + bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21] + bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22] + bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23] + bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24] + d0 = bc4 ^ (bc1<<1 | bc1>>63) + d1 = bc0 ^ (bc2<<1 | bc2>>63) + d2 = bc1 ^ (bc3<<1 | bc3>>63) + d3 = bc2 ^ (bc4<<1 | bc4>>63) + d4 = bc3 ^ (bc0<<1 | bc0>>63) + + bc0 = a[0] ^ d0 + t = a[1] ^ d1 + bc1 = t<<44 | t>>(64-44) + t = a[2] ^ d2 + bc2 = t<<43 | t>>(64-43) + t = a[3] ^ d3 + bc3 = t<<21 | t>>(64-21) + t = a[4] ^ d4 + bc4 = t<<14 | t>>(64-14) + a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i+3] + a[1] = bc1 ^ (bc3 &^ bc2) + a[2] = bc2 ^ (bc4 &^ bc3) + a[3] = bc3 ^ (bc0 &^ bc4) + a[4] = bc4 ^ (bc1 &^ bc0) + + t = a[5] ^ d0 + bc2 = t<<3 | t>>(64-3) + t = a[6] ^ d1 + bc3 = t<<45 | t>>(64-45) + t = a[7] ^ d2 + bc4 = t<<61 | t>>(64-61) + t = a[8] ^ d3 + bc0 = t<<28 | t>>(64-28) + t = a[9] ^ d4 + bc1 = t<<20 | t>>(64-20) + a[5] = bc0 ^ (bc2 &^ bc1) + a[6] = bc1 ^ (bc3 &^ bc2) + a[7] = bc2 ^ (bc4 &^ bc3) + a[8] = bc3 ^ (bc0 &^ bc4) + a[9] = bc4 ^ (bc1 &^ bc0) + + t = a[10] ^ d0 + bc4 = t<<18 | t>>(64-18) + t = a[11] ^ d1 + bc0 = t<<1 | t>>(64-1) + t = a[12] ^ d2 + bc1 = t<<6 | t>>(64-6) + t = a[13] ^ d3 + bc2 = t<<25 | t>>(64-25) + t = a[14] ^ d4 + bc3 = t<<8 | t>>(64-8) + a[10] = bc0 ^ (bc2 &^ bc1) + a[11] = bc1 ^ (bc3 &^ bc2) + a[12] = bc2 ^ (bc4 &^ bc3) + a[13] = bc3 ^ (bc0 &^ bc4) + a[14] = bc4 ^ (bc1 &^ bc0) + + t = a[15] ^ d0 + bc1 = t<<36 | t>>(64-36) + t = a[16] ^ d1 + bc2 = t<<10 | t>>(64-10) + t = a[17] ^ d2 + bc3 = t<<15 | t>>(64-15) + t = a[18] ^ d3 + bc4 = t<<56 | t>>(64-56) + t = a[19] ^ d4 + bc0 = t<<27 | t>>(64-27) + a[15] = bc0 ^ (bc2 &^ bc1) + a[16] = bc1 ^ (bc3 &^ bc2) + a[17] = bc2 ^ (bc4 &^ bc3) + a[18] = bc3 ^ (bc0 &^ bc4) + a[19] = bc4 ^ (bc1 &^ bc0) + + t = a[20] ^ d0 + bc3 = t<<41 | t>>(64-41) + t = a[21] ^ d1 + bc4 = t<<2 | t>>(64-2) + t = a[22] ^ d2 + bc0 = t<<62 | t>>(64-62) + t = a[23] ^ d3 + bc1 = t<<55 | t>>(64-55) + t = a[24] ^ d4 + bc2 = t<<39 | t>>(64-39) + a[20] = bc0 ^ (bc2 &^ bc1) + a[21] = bc1 ^ (bc3 &^ bc2) + a[22] = bc2 ^ (bc4 &^ bc3) + a[23] = bc3 ^ (bc0 &^ bc4) + a[24] = bc4 ^ (bc1 &^ bc0) + } +} diff --git a/vendor/QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb/crypto-sha3/package.json b/vendor/QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb/crypto-sha3/package.json new file mode 100644 index 0000000000000000000000000000000000000000..22ab87b74f205decd038b2d6ff562d4c1fe9b665 --- /dev/null +++ b/vendor/QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb/crypto-sha3/package.json @@ -0,0 +1,9 @@ +{ + "name": "crypto-sha3", + "author": "whyrusleeping", + "version": "1.0.0", + "language": "go", + "gx": { + "dvcsimport": "golang.org/x/crypto/sha3" + } +} \ No newline at end of file diff --git a/vendor/QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb/crypto-sha3/register.go b/vendor/QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb/crypto-sha3/register.go new file mode 100644 index 0000000000000000000000000000000000000000..3cf6a22e093ad380057828362461062268b35101 --- /dev/null +++ b/vendor/QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb/crypto-sha3/register.go @@ -0,0 +1,18 @@ +// Copyright 2014 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.4 + +package sha3 + +import ( + "crypto" +) + +func init() { + crypto.RegisterHash(crypto.SHA3_224, New224) + crypto.RegisterHash(crypto.SHA3_256, New256) + crypto.RegisterHash(crypto.SHA3_384, New384) + crypto.RegisterHash(crypto.SHA3_512, New512) +} diff --git a/vendor/QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb/crypto-sha3/sha3.go b/vendor/QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb/crypto-sha3/sha3.go new file mode 100644 index 0000000000000000000000000000000000000000..c8fd31cb0ba0f5523adea739427e863ce02db92a --- /dev/null +++ b/vendor/QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb/crypto-sha3/sha3.go @@ -0,0 +1,193 @@ +// Copyright 2014 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 sha3 + +// spongeDirection indicates the direction bytes are flowing through the sponge. +type spongeDirection int + +const ( + // spongeAbsorbing indicates that the sponge is absorbing input. + spongeAbsorbing spongeDirection = iota + // spongeSqueezing indicates that the sponge is being squeezed. + spongeSqueezing +) + +const ( + // maxRate is the maximum size of the internal buffer. SHAKE-256 + // currently needs the largest buffer. + maxRate = 168 +) + +type state struct { + // Generic sponge components. + a [25]uint64 // main state of the hash + buf []byte // points into storage + rate int // the number of bytes of state to use + + // dsbyte contains the "domain separation" bits and the first bit of + // the padding. Sections 6.1 and 6.2 of [1] separate the outputs of the + // SHA-3 and SHAKE functions by appending bitstrings to the message. + // Using a little-endian bit-ordering convention, these are "01" for SHA-3 + // and "1111" for SHAKE, or 00000010b and 00001111b, respectively. Then the + // padding rule from section 5.1 is applied to pad the message to a multiple + // of the rate, which involves adding a "1" bit, zero or more "0" bits, and + // a final "1" bit. We merge the first "1" bit from the padding into dsbyte, + // giving 00000110b (0x06) and 00011111b (0x1f). + // [1] http://csrc.nist.gov/publications/drafts/fips-202/fips_202_draft.pdf + // "Draft FIPS 202: SHA-3 Standard: Permutation-Based Hash and + // Extendable-Output Functions (May 2014)" + dsbyte byte + storage [maxRate]byte + + // Specific to SHA-3 and SHAKE. + fixedOutput bool // whether this is a fixed-ouput-length instance + outputLen int // the default output size in bytes + state spongeDirection // whether the sponge is absorbing or squeezing +} + +// BlockSize returns the rate of sponge underlying this hash function. +func (d *state) BlockSize() int { return d.rate } + +// Size returns the output size of the hash function in bytes. +func (d *state) Size() int { return d.outputLen } + +// Reset clears the internal state by zeroing the sponge state and +// the byte buffer, and setting Sponge.state to absorbing. +func (d *state) Reset() { + // Zero the permutation's state. + for i := range d.a { + d.a[i] = 0 + } + d.state = spongeAbsorbing + d.buf = d.storage[:0] +} + +func (d *state) clone() *state { + ret := *d + if ret.state == spongeAbsorbing { + ret.buf = ret.storage[:len(ret.buf)] + } else { + ret.buf = ret.storage[d.rate-cap(d.buf) : d.rate] + } + + return &ret +} + +// permute applies the KeccakF-1600 permutation. It handles +// any input-output buffering. +func (d *state) permute() { + switch d.state { + case spongeAbsorbing: + // If we're absorbing, we need to xor the input into the state + // before applying the permutation. + xorIn(d, d.buf) + d.buf = d.storage[:0] + keccakF1600(&d.a) + case spongeSqueezing: + // If we're squeezing, we need to apply the permutatin before + // copying more output. + keccakF1600(&d.a) + d.buf = d.storage[:d.rate] + copyOut(d, d.buf) + } +} + +// pads appends the domain separation bits in dsbyte, applies +// the multi-bitrate 10..1 padding rule, and permutes the state. +func (d *state) padAndPermute(dsbyte byte) { + if d.buf == nil { + d.buf = d.storage[:0] + } + // Pad with this instance's domain-separator bits. We know that there's + // at least one byte of space in d.buf because, if it were full, + // permute would have been called to empty it. dsbyte also contains the + // first one bit for the padding. See the comment in the state struct. + d.buf = append(d.buf, dsbyte) + zerosStart := len(d.buf) + d.buf = d.storage[:d.rate] + for i := zerosStart; i < d.rate; i++ { + d.buf[i] = 0 + } + // This adds the final one bit for the padding. Because of the way that + // bits are numbered from the LSB upwards, the final bit is the MSB of + // the last byte. + d.buf[d.rate-1] ^= 0x80 + // Apply the permutation + d.permute() + d.state = spongeSqueezing + d.buf = d.storage[:d.rate] + copyOut(d, d.buf) +} + +// Write absorbs more data into the hash's state. It produces an error +// if more data is written to the ShakeHash after writing +func (d *state) Write(p []byte) (written int, err error) { + if d.state != spongeAbsorbing { + panic("sha3: write to sponge after read") + } + if d.buf == nil { + d.buf = d.storage[:0] + } + written = len(p) + + for len(p) > 0 { + if len(d.buf) == 0 && len(p) >= d.rate { + // The fast path; absorb a full "rate" bytes of input and apply the permutation. + xorIn(d, p[:d.rate]) + p = p[d.rate:] + keccakF1600(&d.a) + } else { + // The slow path; buffer the input until we can fill the sponge, and then xor it in. + todo := d.rate - len(d.buf) + if todo > len(p) { + todo = len(p) + } + d.buf = append(d.buf, p[:todo]...) + p = p[todo:] + + // If the sponge is full, apply the permutation. + if len(d.buf) == d.rate { + d.permute() + } + } + } + + return +} + +// Read squeezes an arbitrary number of bytes from the sponge. +func (d *state) Read(out []byte) (n int, err error) { + // If we're still absorbing, pad and apply the permutation. + if d.state == spongeAbsorbing { + d.padAndPermute(d.dsbyte) + } + + n = len(out) + + // Now, do the squeezing. + for len(out) > 0 { + n := copy(out, d.buf) + d.buf = d.buf[n:] + out = out[n:] + + // Apply the permutation if we've squeezed the sponge dry. + if len(d.buf) == 0 { + d.permute() + } + } + + return +} + +// Sum applies padding to the hash state and then squeezes out the desired +// number of output bytes. +func (d *state) Sum(in []byte) []byte { + // Make a copy of the original hash so that caller can keep writing + // and summing. + dup := d.clone() + hash := make([]byte, dup.outputLen) + dup.Read(hash) + return append(in, hash...) +} diff --git a/vendor/QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb/crypto-sha3/sha3_test.go b/vendor/QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb/crypto-sha3/sha3_test.go new file mode 100644 index 0000000000000000000000000000000000000000..caf72f279f1a475f5e6402b3f1244906ddd0af4d --- /dev/null +++ b/vendor/QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb/crypto-sha3/sha3_test.go @@ -0,0 +1,306 @@ +// Copyright 2014 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 sha3 + +// Tests include all the ShortMsgKATs provided by the Keccak team at +// https://github.com/gvanas/KeccakCodePackage +// +// They only include the zero-bit case of the bitwise testvectors +// published by NIST in the draft of FIPS-202. + +import ( + "bytes" + "compress/flate" + "encoding/hex" + "encoding/json" + "hash" + "os" + "strings" + "testing" +) + +const ( + testString = "brekeccakkeccak koax koax" + katFilename = "testdata/keccakKats.json.deflate" +) + +// Internal-use instances of SHAKE used to test against KATs. +func newHashShake128() hash.Hash { + return &state{rate: 168, dsbyte: 0x1f, outputLen: 512} +} +func newHashShake256() hash.Hash { + return &state{rate: 136, dsbyte: 0x1f, outputLen: 512} +} + +// testDigests contains functions returning hash.Hash instances +// with output-length equal to the KAT length for both SHA-3 and +// SHAKE instances. +var testDigests = map[string]func() hash.Hash{ + "SHA3-224": New224, + "SHA3-256": New256, + "SHA3-384": New384, + "SHA3-512": New512, + "SHAKE128": newHashShake128, + "SHAKE256": newHashShake256, +} + +// testShakes contains functions that return ShakeHash instances for +// testing the ShakeHash-specific interface. +var testShakes = map[string]func() ShakeHash{ + "SHAKE128": NewShake128, + "SHAKE256": NewShake256, +} + +// decodeHex converts a hex-encoded string into a raw byte string. +func decodeHex(s string) []byte { + b, err := hex.DecodeString(s) + if err != nil { + panic(err) + } + return b +} + +// structs used to marshal JSON test-cases. +type KeccakKats struct { + Kats map[string][]struct { + Digest string `json:"digest"` + Length int64 `json:"length"` + Message string `json:"message"` + } +} + +func testUnalignedAndGeneric(t *testing.T, testf func(impl string)) { + xorInOrig, copyOutOrig := xorIn, copyOut + xorIn, copyOut = xorInGeneric, copyOutGeneric + testf("generic") + if xorImplementationUnaligned != "generic" { + xorIn, copyOut = xorInUnaligned, copyOutUnaligned + testf("unaligned") + } + xorIn, copyOut = xorInOrig, copyOutOrig +} + +// TestKeccakKats tests the SHA-3 and Shake implementations against all the +// ShortMsgKATs from https://github.com/gvanas/KeccakCodePackage +// (The testvectors are stored in keccakKats.json.deflate due to their length.) +func TestKeccakKats(t *testing.T) { + testUnalignedAndGeneric(t, func(impl string) { + // Read the KATs. + deflated, err := os.Open(katFilename) + if err != nil { + t.Errorf("error opening %s: %s", katFilename, err) + } + file := flate.NewReader(deflated) + dec := json.NewDecoder(file) + var katSet KeccakKats + err = dec.Decode(&katSet) + if err != nil { + t.Errorf("error decoding KATs: %s", err) + } + + // Do the KATs. + for functionName, kats := range katSet.Kats { + d := testDigests[functionName]() + for _, kat := range kats { + d.Reset() + in, err := hex.DecodeString(kat.Message) + if err != nil { + t.Errorf("error decoding KAT: %s", err) + } + d.Write(in[:kat.Length/8]) + got := strings.ToUpper(hex.EncodeToString(d.Sum(nil))) + if got != kat.Digest { + t.Errorf("function=%s, implementation=%s, length=%d\nmessage:\n %s\ngot:\n %s\nwanted:\n %s", + functionName, impl, kat.Length, kat.Message, got, kat.Digest) + t.Logf("wanted %+v", kat) + t.FailNow() + } + continue + } + } + }) +} + +// TestUnalignedWrite tests that writing data in an arbitrary pattern with +// small input buffers. +func testUnalignedWrite(t *testing.T) { + testUnalignedAndGeneric(t, func(impl string) { + buf := sequentialBytes(0x10000) + for alg, df := range testDigests { + d := df() + d.Reset() + d.Write(buf) + want := d.Sum(nil) + d.Reset() + for i := 0; i < len(buf); { + // Cycle through offsets which make a 137 byte sequence. + // Because 137 is prime this sequence should exercise all corner cases. + offsets := [17]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1} + for _, j := range offsets { + if v := len(buf) - i; v < j { + j = v + } + d.Write(buf[i : i+j]) + i += j + } + } + got := d.Sum(nil) + if !bytes.Equal(got, want) { + t.Errorf("Unaligned writes, implementation=%s, alg=%s\ngot %q, want %q", impl, alg, got, want) + } + } + }) +} + +// TestAppend checks that appending works when reallocation is necessary. +func TestAppend(t *testing.T) { + testUnalignedAndGeneric(t, func(impl string) { + d := New224() + + for capacity := 2; capacity <= 66; capacity += 64 { + // The first time around the loop, Sum will have to reallocate. + // The second time, it will not. + buf := make([]byte, 2, capacity) + d.Reset() + d.Write([]byte{0xcc}) + buf = d.Sum(buf) + expected := "0000DF70ADC49B2E76EEE3A6931B93FA41841C3AF2CDF5B32A18B5478C39" + if got := strings.ToUpper(hex.EncodeToString(buf)); got != expected { + t.Errorf("got %s, want %s", got, expected) + } + } + }) +} + +// TestAppendNoRealloc tests that appending works when no reallocation is necessary. +func TestAppendNoRealloc(t *testing.T) { + testUnalignedAndGeneric(t, func(impl string) { + buf := make([]byte, 1, 200) + d := New224() + d.Write([]byte{0xcc}) + buf = d.Sum(buf) + expected := "00DF70ADC49B2E76EEE3A6931B93FA41841C3AF2CDF5B32A18B5478C39" + if got := strings.ToUpper(hex.EncodeToString(buf)); got != expected { + t.Errorf("%s: got %s, want %s", impl, got, expected) + } + }) +} + +// TestSqueezing checks that squeezing the full output a single time produces +// the same output as repeatedly squeezing the instance. +func TestSqueezing(t *testing.T) { + testUnalignedAndGeneric(t, func(impl string) { + for functionName, newShakeHash := range testShakes { + d0 := newShakeHash() + d0.Write([]byte(testString)) + ref := make([]byte, 32) + d0.Read(ref) + + d1 := newShakeHash() + d1.Write([]byte(testString)) + var multiple []byte + for _ = range ref { + one := make([]byte, 1) + d1.Read(one) + multiple = append(multiple, one...) + } + if !bytes.Equal(ref, multiple) { + t.Errorf("%s (%s): squeezing %d bytes one at a time failed", functionName, impl, len(ref)) + } + } + }) +} + +// sequentialBytes produces a buffer of size consecutive bytes 0x00, 0x01, ..., used for testing. +func sequentialBytes(size int) []byte { + result := make([]byte, size) + for i := range result { + result[i] = byte(i) + } + return result +} + +// BenchmarkPermutationFunction measures the speed of the permutation function +// with no input data. +func BenchmarkPermutationFunction(b *testing.B) { + b.SetBytes(int64(200)) + var lanes [25]uint64 + for i := 0; i < b.N; i++ { + keccakF1600(&lanes) + } +} + +// benchmarkHash tests the speed to hash num buffers of buflen each. +func benchmarkHash(b *testing.B, h hash.Hash, size, num int) { + b.StopTimer() + h.Reset() + data := sequentialBytes(size) + b.SetBytes(int64(size * num)) + b.StartTimer() + + var state []byte + for i := 0; i < b.N; i++ { + for j := 0; j < num; j++ { + h.Write(data) + } + state = h.Sum(state[:0]) + } + b.StopTimer() + h.Reset() +} + +// benchmarkShake is specialized to the Shake instances, which don't +// require a copy on reading output. +func benchmarkShake(b *testing.B, h ShakeHash, size, num int) { + b.StopTimer() + h.Reset() + data := sequentialBytes(size) + d := make([]byte, 32) + + b.SetBytes(int64(size * num)) + b.StartTimer() + + for i := 0; i < b.N; i++ { + h.Reset() + for j := 0; j < num; j++ { + h.Write(data) + } + h.Read(d) + } +} + +func BenchmarkSha3_512_MTU(b *testing.B) { benchmarkHash(b, New512(), 1350, 1) } +func BenchmarkSha3_384_MTU(b *testing.B) { benchmarkHash(b, New384(), 1350, 1) } +func BenchmarkSha3_256_MTU(b *testing.B) { benchmarkHash(b, New256(), 1350, 1) } +func BenchmarkSha3_224_MTU(b *testing.B) { benchmarkHash(b, New224(), 1350, 1) } + +func BenchmarkShake128_MTU(b *testing.B) { benchmarkShake(b, NewShake128(), 1350, 1) } +func BenchmarkShake256_MTU(b *testing.B) { benchmarkShake(b, NewShake256(), 1350, 1) } +func BenchmarkShake256_16x(b *testing.B) { benchmarkShake(b, NewShake256(), 16, 1024) } +func BenchmarkShake256_1MiB(b *testing.B) { benchmarkShake(b, NewShake256(), 1024, 1024) } + +func BenchmarkSha3_512_1MiB(b *testing.B) { benchmarkHash(b, New512(), 1024, 1024) } + +func Example_sum() { + buf := []byte("some data to hash") + // A hash needs to be 64 bytes long to have 256-bit collision resistance. + h := make([]byte, 64) + // Compute a 64-byte hash of buf and put it in h. + ShakeSum256(h, buf) +} + +func Example_mac() { + k := []byte("this is a secret key; you should generate a strong random key that's at least 32 bytes long") + buf := []byte("and this is some data to authenticate") + // A MAC with 32 bytes of output has 256-bit security strength -- if you use at least a 32-byte-long key. + h := make([]byte, 32) + d := NewShake256() + // Write the key into the hash. + d.Write(k) + // Now write the data. + d.Write(buf) + // Read 32 bytes of output from the hash into h. + d.Read(h) +} diff --git a/vendor/QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb/crypto-sha3/shake.go b/vendor/QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb/crypto-sha3/shake.go new file mode 100644 index 0000000000000000000000000000000000000000..841f9860f031e92cc10d21be0bdabc1a40ab9f68 --- /dev/null +++ b/vendor/QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb/crypto-sha3/shake.go @@ -0,0 +1,60 @@ +// Copyright 2014 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 sha3 + +// This file defines the ShakeHash interface, and provides +// functions for creating SHAKE instances, as well as utility +// functions for hashing bytes to arbitrary-length output. + +import ( + "io" +) + +// ShakeHash defines the interface to hash functions that +// support arbitrary-length output. +type ShakeHash interface { + // Write absorbs more data into the hash's state. It panics if input is + // written to it after output has been read from it. + io.Writer + + // Read reads more output from the hash; reading affects the hash's + // state. (ShakeHash.Read is thus very different from Hash.Sum) + // It never returns an error. + io.Reader + + // Clone returns a copy of the ShakeHash in its current state. + Clone() ShakeHash + + // Reset resets the ShakeHash to its initial state. + Reset() +} + +func (d *state) Clone() ShakeHash { + return d.clone() +} + +// NewShake128 creates a new SHAKE128 variable-output-length ShakeHash. +// Its generic security strength is 128 bits against all attacks if at +// least 32 bytes of its output are used. +func NewShake128() ShakeHash { return &state{rate: 168, dsbyte: 0x1f} } + +// NewShake256 creates a new SHAKE128 variable-output-length ShakeHash. +// Its generic security strength is 256 bits against all attacks if +// at least 64 bytes of its output are used. +func NewShake256() ShakeHash { return &state{rate: 136, dsbyte: 0x1f} } + +// ShakeSum128 writes an arbitrary-length digest of data into hash. +func ShakeSum128(hash, data []byte) { + h := NewShake128() + h.Write(data) + h.Read(hash) +} + +// ShakeSum256 writes an arbitrary-length digest of data into hash. +func ShakeSum256(hash, data []byte) { + h := NewShake256() + h.Write(data) + h.Read(hash) +} diff --git a/vendor/QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb/crypto-sha3/testdata/keccakKats.json.deflate b/vendor/QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb/crypto-sha3/testdata/keccakKats.json.deflate new file mode 100644 index 0000000000000000000000000000000000000000..62e85ae24236b46c09e5cfa84c71c69f5cc33cf6 Binary files /dev/null and b/vendor/QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb/crypto-sha3/testdata/keccakKats.json.deflate differ diff --git a/vendor/QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb/crypto-sha3/xor.go b/vendor/QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb/crypto-sha3/xor.go new file mode 100644 index 0000000000000000000000000000000000000000..d622979c1152653799e99e75de381851b7176681 --- /dev/null +++ b/vendor/QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb/crypto-sha3/xor.go @@ -0,0 +1,16 @@ +// Copyright 2015 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 !amd64,!386 appengine + +package sha3 + +var ( + xorIn = xorInGeneric + copyOut = copyOutGeneric + xorInUnaligned = xorInGeneric + copyOutUnaligned = copyOutGeneric +) + +const xorImplementationUnaligned = "generic" diff --git a/vendor/QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb/crypto-sha3/xor_generic.go b/vendor/QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb/crypto-sha3/xor_generic.go new file mode 100644 index 0000000000000000000000000000000000000000..fd35f02ef6e0c98e2f7dbef539920814837455f9 --- /dev/null +++ b/vendor/QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb/crypto-sha3/xor_generic.go @@ -0,0 +1,28 @@ +// Copyright 2015 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 sha3 + +import "encoding/binary" + +// xorInGeneric xors the bytes in buf into the state; it +// makes no non-portable assumptions about memory layout +// or alignment. +func xorInGeneric(d *state, buf []byte) { + n := len(buf) / 8 + + for i := 0; i < n; i++ { + a := binary.LittleEndian.Uint64(buf) + d.a[i] ^= a + buf = buf[8:] + } +} + +// copyOutGeneric copies ulint64s to a byte buffer. +func copyOutGeneric(d *state, b []byte) { + for i := 0; len(b) >= 8; i++ { + binary.LittleEndian.PutUint64(b, d.a[i]) + b = b[8:] + } +} diff --git a/vendor/QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb/crypto-sha3/xor_unaligned.go b/vendor/QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb/crypto-sha3/xor_unaligned.go new file mode 100644 index 0000000000000000000000000000000000000000..c7851a1d8509429c6e615137cb6aa920e8343d67 --- /dev/null +++ b/vendor/QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb/crypto-sha3/xor_unaligned.go @@ -0,0 +1,58 @@ +// Copyright 2015 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 amd64 386 +// +build !appengine + +package sha3 + +import "unsafe" + +func xorInUnaligned(d *state, buf []byte) { + bw := (*[maxRate / 8]uint64)(unsafe.Pointer(&buf[0])) + n := len(buf) + if n >= 72 { + d.a[0] ^= bw[0] + d.a[1] ^= bw[1] + d.a[2] ^= bw[2] + d.a[3] ^= bw[3] + d.a[4] ^= bw[4] + d.a[5] ^= bw[5] + d.a[6] ^= bw[6] + d.a[7] ^= bw[7] + d.a[8] ^= bw[8] + } + if n >= 104 { + d.a[9] ^= bw[9] + d.a[10] ^= bw[10] + d.a[11] ^= bw[11] + d.a[12] ^= bw[12] + } + if n >= 136 { + d.a[13] ^= bw[13] + d.a[14] ^= bw[14] + d.a[15] ^= bw[15] + d.a[16] ^= bw[16] + } + if n >= 144 { + d.a[17] ^= bw[17] + } + if n >= 168 { + d.a[18] ^= bw[18] + d.a[19] ^= bw[19] + d.a[20] ^= bw[20] + } +} + +func copyOutUnaligned(d *state, buf []byte) { + ab := (*[maxRate]uint8)(unsafe.Pointer(&d.a[0])) + copy(buf, ab[:]) +} + +var ( + xorIn = xorInUnaligned + copyOut = copyOutUnaligned +) + +const xorImplementationUnaligned = "unaligned" diff --git a/vendor/QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr/.travis.yml b/vendor/QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr/.travis.yml new file mode 100644 index 0000000000000000000000000000000000000000..7b571f4004282938c728659dd5951b2feb39e0b4 --- /dev/null +++ b/vendor/QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr/.travis.yml @@ -0,0 +1,9 @@ +language: go + +go: + - 1.3 + - release + - tip + +script: + - go test -race -cpu=5 -v ./... diff --git a/vendor/QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr/LICENSE b/vendor/QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..c7386b3c940d8aa7baea2dd6fec2908fed562b89 --- /dev/null +++ b/vendor/QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Juan Batiz-Benet + +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. + +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. diff --git a/vendor/QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr/README.md b/vendor/QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr/README.md new file mode 100644 index 0000000000000000000000000000000000000000..42c23fff852e0ca86466ebfa766edb9ac11099a7 --- /dev/null +++ b/vendor/QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr/README.md @@ -0,0 +1,58 @@ +# go-multiaddr + +[multiaddr](https://github.com/jbenet/multiaddr) implementation in Go. + +## Example + +### Simple + +```go +import ma "github.com/jbenet/go-multiaddr" + +// construct from a string (err signals parse failure) +m1, err := ma.NewMultiaddr("/ip4/127.0.0.1/udp/1234") + +// construct from bytes (err signals parse failure) +m2, err := ma.NewMultiaddrBytes(m1.Bytes()) + +// true +strings.Equal(m1.String(), "/ip4/127.0.0.1/udp/1234") +strings.Equal(m1.String(), m2.String()) +bytes.Equal(m1.Bytes(), m2.Bytes()) +m1.Equal(m2) +m2.Equal(m1) +``` + +### Protocols + +```go +// get the multiaddr protocol description objects +addr.Protocols() +// []Protocol{ +// Protocol{ Code: 4, Name: 'ip4', Size: 32}, +// Protocol{ Code: 17, Name: 'udp', Size: 16}, +// } +``` + +### En/decapsulate + +```go +m.Encapsulate(ma.NewMultiaddr("/sctp/5678")) +// +m.Decapsulate(ma.NewMultiaddr("/udp")) // up to + inc last occurrence of subaddr +// +``` + +### Tunneling + +Multiaddr allows expressing tunnels very nicely. + +```js +printer, _ := ma.NewMultiaddr("/ip4/192.168.0.13/tcp/80") +proxy, _ := ma.NewMultiaddr("/ip4/10.20.30.40/tcp/443") +printerOverProxy := proxy.Encapsulate(printer) +// /ip4/10.20.30.40/tcp/443/ip4/192.168.0.13/tcp/80 + +proxyAgain := printerOverProxy.Decapsulate(printer) +// /ip4/10.20.30.40/tcp/443 +``` diff --git a/vendor/QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr/codec.go b/vendor/QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr/codec.go new file mode 100644 index 0000000000000000000000000000000000000000..1eacf46045198fc63678f964c74344f1831d96cd --- /dev/null +++ b/vendor/QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr/codec.go @@ -0,0 +1,244 @@ +package multiaddr + +import ( + "encoding/base32" + "encoding/binary" + "errors" + "fmt" + "net" + "strconv" + "strings" + + mh "QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash" +) + +func stringToBytes(s string) ([]byte, error) { + + // consume trailing slashes + s = strings.TrimRight(s, "/") + + b := []byte{} + sp := strings.Split(s, "/") + + if sp[0] != "" { + return nil, fmt.Errorf("invalid multiaddr, must begin with /") + } + + // consume first empty elem + sp = sp[1:] + + for len(sp) > 0 { + p := ProtocolWithName(sp[0]) + if p.Code == 0 { + return nil, fmt.Errorf("no protocol with name %s", sp[0]) + } + b = append(b, CodeToVarint(p.Code)...) + sp = sp[1:] + + if p.Size == 0 { // no length. + continue + } + + if len(sp) < 1 { + return nil, fmt.Errorf("protocol requires address, none given: %s", p.Name) + } + a, err := addressStringToBytes(p, sp[0]) + if err != nil { + return nil, fmt.Errorf("failed to parse %s: %s %s", p.Name, sp[0], err) + } + b = append(b, a...) + sp = sp[1:] + } + return b, nil +} + +func bytesToString(b []byte) (ret string, err error) { + // panic handler, in case we try accessing bytes incorrectly. + defer func() { + if e := recover(); e != nil { + ret = "" + switch e := e.(type) { + case error: + err = e + case string: + err = errors.New(e) + default: + err = fmt.Errorf("%v", e) + } + } + }() + + s := "" + + for len(b) > 0 { + + code, n := ReadVarintCode(b) + b = b[n:] + p := ProtocolWithCode(code) + if p.Code == 0 { + return "", fmt.Errorf("no protocol with code %d", code) + } + s += "/" + p.Name + + if p.Size == 0 { + continue + } + + size := sizeForAddr(p, b) + a, err := addressBytesToString(p, b[:size]) + if err != nil { + return "", err + } + if len(a) > 0 { + s += "/" + a + } + b = b[size:] + } + + return s, nil +} + +func sizeForAddr(p Protocol, b []byte) int { + switch { + case p.Size > 0: + return (p.Size / 8) + case p.Size == 0: + return 0 + default: + size, n := ReadVarintCode(b) + return size + n + } +} + +func bytesSplit(b []byte) (ret [][]byte, err error) { + // panic handler, in case we try accessing bytes incorrectly. + defer func() { + if e := recover(); e != nil { + ret = [][]byte{} + err = e.(error) + } + }() + + ret = [][]byte{} + for len(b) > 0 { + code, n := ReadVarintCode(b) + p := ProtocolWithCode(code) + if p.Code == 0 { + return [][]byte{}, fmt.Errorf("no protocol with code %d", b[0]) + } + + size := sizeForAddr(p, b[n:]) + length := n + size + ret = append(ret, b[:length]) + b = b[length:] + } + + return ret, nil +} + +func addressStringToBytes(p Protocol, s string) ([]byte, error) { + switch p.Code { + + case P_IP4: // ipv4 + i := net.ParseIP(s).To4() + if i == nil { + return nil, fmt.Errorf("failed to parse ip4 addr: %s", s) + } + return i, nil + + case P_IP6: // ipv6 + i := net.ParseIP(s).To16() + if i == nil { + return nil, fmt.Errorf("failed to parse ip6 addr: %s", s) + } + return i, nil + + // tcp udp dccp sctp + case P_TCP, P_UDP, P_DCCP, P_SCTP: + i, err := strconv.Atoi(s) + if err != nil { + return nil, fmt.Errorf("failed to parse %s addr: %s", p.Name, err) + } + if i >= 65536 { + return nil, fmt.Errorf("failed to parse %s addr: %s", p.Name, "greater than 65536") + } + b := make([]byte, 2) + binary.BigEndian.PutUint16(b, uint16(i)) + return b, nil + + case P_ONION: + addr := strings.Split(s, ":") + if len(addr) != 2 { + return nil, fmt.Errorf("failed to parse %s addr: %s does not contain a port number.", p.Name, s) + } + + // onion address without the ".onion" substring + if len(addr[0]) != 16 { + return nil, fmt.Errorf("failed to parse %s addr: %s not a Tor onion address.", p.Name, s) + } + onionHostBytes, err := base32.StdEncoding.DecodeString(strings.ToUpper(addr[0])) + if err != nil { + return nil, fmt.Errorf("failed to decode base32 %s addr: %s %s", p.Name, s, err) + } + + // onion port number + i, err := strconv.Atoi(addr[1]) + if err != nil { + return nil, fmt.Errorf("failed to parse %s addr: %s", p.Name, err) + } + if i >= 65536 { + return nil, fmt.Errorf("failed to parse %s addr: %s", p.Name, "port greater than 65536") + } + if i < 1 { + return nil, fmt.Errorf("failed to parse %s addr: %s", p.Name, "port less than 1") + } + + onionPortBytes := make([]byte, 2) + binary.BigEndian.PutUint16(onionPortBytes, uint16(i)) + bytes := []byte{} + bytes = append(bytes, onionHostBytes...) + bytes = append(bytes, onionPortBytes...) + return bytes, nil + + case P_IPFS: // ipfs + // the address is a varint prefixed multihash string representation + m, err := mh.FromB58String(s) + if err != nil { + return nil, fmt.Errorf("failed to parse ipfs addr: %s %s", s, err) + } + size := CodeToVarint(len(m)) + b := append(size, m...) + return b, nil + } + + return []byte{}, fmt.Errorf("failed to parse %s addr: unknown", p.Name) +} + +func addressBytesToString(p Protocol, b []byte) (string, error) { + switch p.Code { + + // ipv4,6 + case P_IP4, P_IP6: + return net.IP(b).String(), nil + + // tcp udp dccp sctp + case P_TCP, P_UDP, P_DCCP, P_SCTP: + i := binary.BigEndian.Uint16(b) + return strconv.Itoa(int(i)), nil + + case P_IPFS: // ipfs + // the address is a varint-prefixed multihash string representation + size, n := ReadVarintCode(b) + b = b[n:] + if len(b) != size { + panic("inconsistent lengths") + } + m, err := mh.Cast(b) + if err != nil { + return "", err + } + return m.B58String(), nil + } + + return "", fmt.Errorf("unknown protocol") +} diff --git a/vendor/QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr/doc.go b/vendor/QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr/doc.go new file mode 100644 index 0000000000000000000000000000000000000000..c26e443cbd254565201cca01c5491dea372cc82c --- /dev/null +++ b/vendor/QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr/doc.go @@ -0,0 +1,36 @@ +/* +Package multiaddr provides an implementation of the Multiaddr network +address format. Multiaddr emphasizes explicitness, self-description, and +portability. It allows applications to treat addresses as opaque tokens, +and to avoid making assumptions about the address representation (e.g. length). +Learn more at https://github.com/jbenet/multiaddr + +Basic Use: + + import ( + "bytes" + "strings" + ma "github.com/jbenet/go-multiaddr" + ) + + // construct from a string (err signals parse failure) + m1, err := ma.NewMultiaddr("/ip4/127.0.0.1/udp/1234") + + // construct from bytes (err signals parse failure) + m2, err := ma.NewMultiaddrBytes(m1.Bytes()) + + // true + strings.Equal(m1.String(), "/ip4/127.0.0.1/udp/1234") + strings.Equal(m1.String(), m2.String()) + bytes.Equal(m1.Bytes(), m2.Bytes()) + m1.Equal(m2) + m2.Equal(m1) + + // tunneling (en/decap) + printer, _ := ma.NewMultiaddr("/ip4/192.168.0.13/tcp/80") + proxy, _ := ma.NewMultiaddr("/ip4/10.20.30.40/tcp/443") + printerOverProxy := proxy.Encapsulate(printer) + proxyAgain := printerOverProxy.Decapsulate(printer) + +*/ +package multiaddr diff --git a/vendor/QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr/interface.go b/vendor/QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr/interface.go new file mode 100644 index 0000000000000000000000000000000000000000..512cb623f54872268f8f8d3abeafd21f1cd5a41f --- /dev/null +++ b/vendor/QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr/interface.go @@ -0,0 +1,42 @@ +package multiaddr + +/* +Multiaddr is a cross-protocol, cross-platform format for representing +internet addresses. It emphasizes explicitness and self-description. +Learn more here: https://github.com/jbenet/multiaddr + +Multiaddrs have both a binary and string representation. + + import ma "github.com/jbenet/go-multiaddr" + + addr, err := ma.NewMultiaddr("/ip4/1.2.3.4/tcp/80") + // err non-nil when parsing failed. + +*/ +type Multiaddr interface { + // Equal returns whether two Multiaddrs are exactly equal + Equal(Multiaddr) bool + + // Bytes returns the []byte representation of this Multiaddr + Bytes() []byte + + // String returns the string representation of this Multiaddr + // (may panic if internal state is corrupted) + String() string + + // Protocols returns the list of Protocols this Multiaddr includes + // will panic if protocol code incorrect (and bytes accessed incorrectly) + Protocols() []Protocol + + // Encapsulate wraps this Multiaddr around another. For example: + // + // /ip4/1.2.3.4 encapsulate /tcp/80 = /ip4/1.2.3.4/tcp/80 + // + Encapsulate(Multiaddr) Multiaddr + + // Decapsultate removes a Multiaddr wrapping. For example: + // + // /ip4/1.2.3.4/tcp/80 decapsulate /ip4/1.2.3.4 = /tcp/80 + // + Decapsulate(Multiaddr) Multiaddr +} diff --git a/vendor/QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr/multiaddr.go b/vendor/QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr/multiaddr.go new file mode 100644 index 0000000000000000000000000000000000000000..1cb7ad4e9c9c85d68aee957630bd4fbe733dec28 --- /dev/null +++ b/vendor/QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr/multiaddr.go @@ -0,0 +1,115 @@ +package multiaddr + +import ( + "bytes" + "fmt" + "strings" +) + +// multiaddr is the data structure representing a Multiaddr +type multiaddr struct { + bytes []byte +} + +// NewMultiaddr parses and validates an input string, returning a *Multiaddr +func NewMultiaddr(s string) (Multiaddr, error) { + b, err := stringToBytes(s) + if err != nil { + return nil, err + } + return &multiaddr{bytes: b}, nil +} + +// NewMultiaddrBytes initializes a Multiaddr from a byte representation. +// It validates it as an input string. +func NewMultiaddrBytes(b []byte) (Multiaddr, error) { + s, err := bytesToString(b) + if err != nil { + return nil, err + } + return NewMultiaddr(s) +} + +// Equal tests whether two multiaddrs are equal +func (m *multiaddr) Equal(m2 Multiaddr) bool { + return bytes.Equal(m.bytes, m2.Bytes()) +} + +// Bytes returns the []byte representation of this Multiaddr +func (m *multiaddr) Bytes() []byte { + // consider returning copy to prevent changing underneath us? + cpy := make([]byte, len(m.bytes)) + copy(cpy, m.bytes) + return cpy +} + +// String returns the string representation of a Multiaddr +func (m *multiaddr) String() string { + s, err := bytesToString(m.bytes) + if err != nil { + panic("multiaddr failed to convert back to string. corrupted?") + } + return s +} + +// Protocols returns the list of protocols this Multiaddr has. +// will panic in case we access bytes incorrectly. +func (m *multiaddr) Protocols() []Protocol { + + // panic handler, in case we try accessing bytes incorrectly. + defer func() { + if e := recover(); e != nil { + err := e.(error) + panic("Multiaddr.Protocols error: " + err.Error()) + } + }() + + size := 0 + ps := []Protocol{} + b := m.bytes[:] + for len(b) > 0 { + code, n := ReadVarintCode(b) + p := ProtocolWithCode(code) + if p.Code == 0 { + // this is a panic (and not returning err) because this should've been + // caught on constructing the Multiaddr + panic(fmt.Errorf("no protocol with code %d", b[0])) + } + ps = append(ps, p) + b = b[n:] + + size = sizeForAddr(p, b) + b = b[size:] + } + return ps +} + +// Encapsulate wraps a given Multiaddr, returning the resulting joined Multiaddr +func (m *multiaddr) Encapsulate(o Multiaddr) Multiaddr { + mb := m.bytes + ob := o.Bytes() + + b := make([]byte, len(mb)+len(ob)) + copy(b, mb) + copy(b[len(mb):], ob) + return &multiaddr{bytes: b} +} + +// Decapsulate unwraps Multiaddr up until the given Multiaddr is found. +func (m *multiaddr) Decapsulate(o Multiaddr) Multiaddr { + s1 := m.String() + s2 := o.String() + i := strings.LastIndex(s1, s2) + if i < 0 { + // if multiaddr not contained, returns a copy. + cpy := make([]byte, len(m.bytes)) + copy(cpy, m.bytes) + return &multiaddr{bytes: cpy} + } + + ma, err := NewMultiaddr(s1[:i]) + if err != nil { + panic("Multiaddr.Decapsulate incorrect byte boundaries.") + } + return ma +} diff --git a/vendor/QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr/multiaddr_test.go b/vendor/QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr/multiaddr_test.go new file mode 100644 index 0000000000000000000000000000000000000000..3a60751f15d65dbe04e17520f1861d498b8b8587 --- /dev/null +++ b/vendor/QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr/multiaddr_test.go @@ -0,0 +1,302 @@ +package multiaddr + +import ( + "bytes" + "encoding/hex" + "testing" +) + +func newMultiaddr(t *testing.T, a string) Multiaddr { + m, err := NewMultiaddr(a) + if err != nil { + t.Error(err) + } + return m +} + +func TestConstructFails(t *testing.T) { + cases := []string{ + "/ip4", + "/ip4/::1", + "/ip4/fdpsofodsajfdoisa", + "/ip6", + "/udp", + "/tcp", + "/sctp", + "/udp/65536", + "/tcp/65536", + "/onion/9imaq4ygg2iegci7:80", + "/onion/aaimaq4ygg2iegci7:80", + "/onion/timaq4ygg2iegci7:0", + "/onion/timaq4ygg2iegci7:-1", + "/onion/timaq4ygg2iegci7", + "/onion/timaq4ygg2iegci@:666", + "/udp/1234/sctp", + "/udp/1234/udt/1234", + "/udp/1234/utp/1234", + "/ip4/127.0.0.1/udp/jfodsajfidosajfoidsa", + "/ip4/127.0.0.1/udp", + "/ip4/127.0.0.1/tcp/jfodsajfidosajfoidsa", + "/ip4/127.0.0.1/tcp", + "/ip4/127.0.0.1/ipfs", + "/ip4/127.0.0.1/ipfs/tcp", + } + + for _, a := range cases { + if _, err := NewMultiaddr(a); err == nil { + t.Errorf("should have failed: %s - %s", a, err) + } + } +} + +func TestConstructSucceeds(t *testing.T) { + cases := []string{ + "/ip4/1.2.3.4", + "/ip4/0.0.0.0", + "/ip6/::1", + "/ip6/2601:9:4f81:9700:803e:ca65:66e8:c21", + "/onion/timaq4ygg2iegci7:1234", + "/onion/timaq4ygg2iegci7:80/http", + "/udp/0", + "/tcp/0", + "/sctp/0", + "/udp/1234", + "/tcp/1234", + "/sctp/1234", + "/udp/65535", + "/tcp/65535", + "/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC", + "/udp/1234/sctp/1234", + "/udp/1234/udt", + "/udp/1234/utp", + "/tcp/1234/http", + "/tcp/1234/https", + "/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC/tcp/1234", + "/ip4/127.0.0.1/udp/1234", + "/ip4/127.0.0.1/udp/0", + "/ip4/127.0.0.1/tcp/1234", + "/ip4/127.0.0.1/tcp/1234/", + "/ip4/127.0.0.1/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC", + "/ip4/127.0.0.1/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC/tcp/1234", + } + + for _, a := range cases { + if _, err := NewMultiaddr(a); err != nil { + t.Errorf("should have succeeded: %s -- %s", a, err) + } + } +} + +func TestEqual(t *testing.T) { + m1 := newMultiaddr(t, "/ip4/127.0.0.1/udp/1234") + m2 := newMultiaddr(t, "/ip4/127.0.0.1/tcp/1234") + m3 := newMultiaddr(t, "/ip4/127.0.0.1/tcp/1234") + m4 := newMultiaddr(t, "/ip4/127.0.0.1/tcp/1234/") + + if m1.Equal(m2) { + t.Error("should not be equal") + } + + if m2.Equal(m1) { + t.Error("should not be equal") + } + + if !m2.Equal(m3) { + t.Error("should be equal") + } + + if !m3.Equal(m2) { + t.Error("should be equal") + } + + if !m1.Equal(m1) { + t.Error("should be equal") + } + + if !m2.Equal(m4) { + t.Error("should be equal") + } + + if !m4.Equal(m3) { + t.Error("should be equal") + } +} + +func TestStringToBytes(t *testing.T) { + + testString := func(s string, h string) { + b1, err := hex.DecodeString(h) + if err != nil { + t.Error("failed to decode hex", h) + } + + b2, err := stringToBytes(s) + if err != nil { + t.Error("failed to convert", s) + } + + if !bytes.Equal(b1, b2) { + t.Error("failed to convert", s, "to", b1, "got", b2) + } + } + + testString("/ip4/127.0.0.1/udp/1234", "047f0000011104d2") + testString("/ip4/127.0.0.1/tcp/4321", "047f0000010610e1") + testString("/ip4/127.0.0.1/udp/1234/ip4/127.0.0.1/tcp/4321", "047f0000011104d2047f0000010610e1") +} + +func TestBytesToString(t *testing.T) { + + testString := func(s1 string, h string) { + b, err := hex.DecodeString(h) + if err != nil { + t.Error("failed to decode hex", h) + } + + s2, err := bytesToString(b) + if err != nil { + t.Error("failed to convert", b) + } + + if s1 != s2 { + t.Error("failed to convert", b, "to", s1, "got", s2) + } + } + + testString("/ip4/127.0.0.1/udp/1234", "047f0000011104d2") + testString("/ip4/127.0.0.1/tcp/4321", "047f0000010610e1") + testString("/ip4/127.0.0.1/udp/1234/ip4/127.0.0.1/tcp/4321", "047f0000011104d2047f0000010610e1") +} + +func TestBytesSplitAndJoin(t *testing.T) { + + testString := func(s string, res []string) { + m, err := NewMultiaddr(s) + if err != nil { + t.Fatal("failed to convert", s, err) + } + + split := Split(m) + if len(split) != len(res) { + t.Error("not enough split components", split) + return + } + + for i, a := range split { + if a.String() != res[i] { + t.Errorf("split component failed: %s != %s", a, res[i]) + } + } + + joined := Join(split...) + if !m.Equal(joined) { + t.Errorf("joined components failed: %s != %s", m, joined) + } + + // modifying underlying bytes is fine. + m2 := m.(*multiaddr) + for i := range m2.bytes { + m2.bytes[i] = 0 + } + + for i, a := range split { + if a.String() != res[i] { + t.Errorf("split component failed: %s != %s", a, res[i]) + } + } + } + + testString("/ip4/1.2.3.4/udp/1234", []string{"/ip4/1.2.3.4", "/udp/1234"}) + testString("/ip4/1.2.3.4/tcp/1/ip4/2.3.4.5/udp/2", + []string{"/ip4/1.2.3.4", "/tcp/1", "/ip4/2.3.4.5", "/udp/2"}) + testString("/ip4/1.2.3.4/utp/ip4/2.3.4.5/udp/2/udt", + []string{"/ip4/1.2.3.4", "/utp", "/ip4/2.3.4.5", "/udp/2", "/udt"}) +} + +func TestProtocols(t *testing.T) { + m, err := NewMultiaddr("/ip4/127.0.0.1/udp/1234") + if err != nil { + t.Error("failed to construct", "/ip4/127.0.0.1/udp/1234") + } + + ps := m.Protocols() + if ps[0].Code != ProtocolWithName("ip4").Code { + t.Error(ps[0], ProtocolWithName("ip4")) + t.Error("failed to get ip4 protocol") + } + + if ps[1].Code != ProtocolWithName("udp").Code { + t.Error(ps[1], ProtocolWithName("udp")) + t.Error("failed to get udp protocol") + } + +} + +func TestProtocolsWithString(t *testing.T) { + pwn := ProtocolWithName + good := map[string][]Protocol{ + "/ip4": []Protocol{pwn("ip4")}, + "/ip4/tcp": []Protocol{pwn("ip4"), pwn("tcp")}, + "ip4/tcp/udp/ip6": []Protocol{pwn("ip4"), pwn("tcp"), pwn("udp"), pwn("ip6")}, + "////////ip4/tcp": []Protocol{pwn("ip4"), pwn("tcp")}, + "ip4/udp/////////": []Protocol{pwn("ip4"), pwn("udp")}, + "////////ip4/tcp////////": []Protocol{pwn("ip4"), pwn("tcp")}, + } + + for s, ps1 := range good { + ps2, err := ProtocolsWithString(s) + if err != nil { + t.Error("ProtocolsWithString(%s) should have succeeded", s) + } + + for i, ps1p := range ps1 { + ps2p := ps2[i] + if ps1p.Code != ps2p.Code { + t.Errorf("mismatch: %s != %s, %s", ps1p.Name, ps2p.Name, s) + } + } + } + + bad := []string{ + "dsijafd", // bogus proto + "/ip4/tcp/fidosafoidsa", // bogus proto + "////////ip4/tcp/21432141/////////", // bogus proto + "////////ip4///////tcp/////////", // empty protos in between + } + + for _, s := range bad { + if _, err := ProtocolsWithString(s); err == nil { + t.Error("ProtocolsWithString(%s) should have failed", s) + } + } + +} + +func TestEncapsulate(t *testing.T) { + m, err := NewMultiaddr("/ip4/127.0.0.1/udp/1234") + if err != nil { + t.Error(err) + } + + m2, err := NewMultiaddr("/udp/5678") + if err != nil { + t.Error(err) + } + + b := m.Encapsulate(m2) + if s := b.String(); s != "/ip4/127.0.0.1/udp/1234/udp/5678" { + t.Error("encapsulate /ip4/127.0.0.1/udp/1234/udp/5678 failed.", s) + } + + m3, _ := NewMultiaddr("/udp/5678") + c := b.Decapsulate(m3) + if s := c.String(); s != "/ip4/127.0.0.1/udp/1234" { + t.Error("decapsulate /udp failed.", "/ip4/127.0.0.1/udp/1234", s) + } + + m4, _ := NewMultiaddr("/ip4/127.0.0.1") + d := c.Decapsulate(m4) + if s := d.String(); s != "" { + t.Error("decapsulate /ip4 failed.", "/", s) + } +} diff --git a/vendor/QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr/package.json b/vendor/QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr/package.json new file mode 100644 index 0000000000000000000000000000000000000000..abb59f9337ff43addf9c1683ced45d34ce4440fb --- /dev/null +++ b/vendor/QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr/package.json @@ -0,0 +1,16 @@ +{ + "name": "go-multiaddr", + "author": "whyrusleeping", + "version": "1.0.0", + "gxDependencies": [ + { + "name": "go-multihash", + "hash": "QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy", + "version": "1.0.0" + } + ], + "language": "go", + "gx": { + "dvcsimport": "github.com/jbenet/go-multiaddr" + } +} \ No newline at end of file diff --git a/vendor/QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr/protocols.csv b/vendor/QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr/protocols.csv new file mode 100644 index 0000000000000000000000000000000000000000..fa27ba34b49e674fd24d3f6bffb1379e0dc56725 --- /dev/null +++ b/vendor/QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr/protocols.csv @@ -0,0 +1,13 @@ +code size name +4 32 ip4 +6 16 tcp +17 16 udp +33 16 dccp +41 128 ip6 +132 16 sctp +301 0 udt +302 0 utp +421 V ipfs +480 0 http +443 0 https +444 10 onion \ No newline at end of file diff --git a/vendor/QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr/protocols.go b/vendor/QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr/protocols.go new file mode 100644 index 0000000000000000000000000000000000000000..c233cef128f5bdbb5fbabe9137a5a720cfdc0c91 --- /dev/null +++ b/vendor/QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr/protocols.go @@ -0,0 +1,118 @@ +package multiaddr + +import ( + "encoding/binary" + "fmt" + "strings" +) + +// Protocol is a Multiaddr protocol description structure. +type Protocol struct { + Code int + Size int // a size of -1 indicates a length-prefixed variable size + Name string + VCode []byte +} + +// replicating table here to: +// 1. avoid parsing the csv +// 2. ensuring errors in the csv don't screw up code. +// 3. changing a number has to happen in two places. +const ( + P_IP4 = 4 + P_TCP = 6 + P_UDP = 17 + P_DCCP = 33 + P_IP6 = 41 + P_SCTP = 132 + P_UTP = 301 + P_UDT = 302 + P_IPFS = 421 + P_HTTP = 480 + P_HTTPS = 443 + P_ONION = 444 +) + +// These are special sizes +const ( + LengthPrefixedVarSize = -1 +) + +// Protocols is the list of multiaddr protocols supported by this module. +var Protocols = []Protocol{ + Protocol{P_IP4, 32, "ip4", CodeToVarint(P_IP4)}, + Protocol{P_TCP, 16, "tcp", CodeToVarint(P_TCP)}, + Protocol{P_UDP, 16, "udp", CodeToVarint(P_UDP)}, + Protocol{P_DCCP, 16, "dccp", CodeToVarint(P_DCCP)}, + Protocol{P_IP6, 128, "ip6", CodeToVarint(P_IP6)}, + // these require varint: + Protocol{P_SCTP, 16, "sctp", CodeToVarint(P_SCTP)}, + Protocol{P_ONION, 80, "onion", CodeToVarint(P_ONION)}, + Protocol{P_UTP, 0, "utp", CodeToVarint(P_UTP)}, + Protocol{P_UDT, 0, "udt", CodeToVarint(P_UDT)}, + Protocol{P_HTTP, 0, "http", CodeToVarint(P_HTTP)}, + Protocol{P_HTTPS, 0, "https", CodeToVarint(P_HTTPS)}, + Protocol{P_IPFS, LengthPrefixedVarSize, "ipfs", CodeToVarint(P_IPFS)}, +} + +// ProtocolWithName returns the Protocol description with given string name. +func ProtocolWithName(s string) Protocol { + for _, p := range Protocols { + if p.Name == s { + return p + } + } + return Protocol{} +} + +// ProtocolWithCode returns the Protocol description with given protocol code. +func ProtocolWithCode(c int) Protocol { + for _, p := range Protocols { + if p.Code == c { + return p + } + } + return Protocol{} +} + +// ProtocolsWithString returns a slice of protocols matching given string. +func ProtocolsWithString(s string) ([]Protocol, error) { + s = strings.Trim(s, "/") + sp := strings.Split(s, "/") + if len(sp) == 0 { + return nil, nil + } + + t := make([]Protocol, len(sp)) + for i, name := range sp { + p := ProtocolWithName(name) + if p.Code == 0 { + return nil, fmt.Errorf("no protocol with name: %s", name) + } + t[i] = p + } + return t, nil +} + +// CodeToVarint converts an integer to a varint-encoded []byte +func CodeToVarint(num int) []byte { + buf := make([]byte, (num/7)+1) // varint package is uint64 + n := binary.PutUvarint(buf, uint64(num)) + return buf[:n] +} + +// VarintToCode converts a varint-encoded []byte to an integer protocol code +func VarintToCode(buf []byte) int { + num, _ := ReadVarintCode(buf) + return num +} + +// ReadVarintCode reads a varint code from the beginning of buf. +// returns the code, and the number of bytes read. +func ReadVarintCode(buf []byte) (int, int) { + num, n := binary.Uvarint(buf) + if n < 0 { + panic("varints larger than uint64 not yet supported") + } + return int(num), n +} diff --git a/vendor/QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr/util.go b/vendor/QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr/util.go new file mode 100644 index 0000000000000000000000000000000000000000..d1b54afbb6a64260c8c5a154e42d0e9a8d03cd6b --- /dev/null +++ b/vendor/QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr/util.go @@ -0,0 +1,56 @@ +package multiaddr + +import "fmt" + +// Split returns the sub-address portions of a multiaddr. +func Split(m Multiaddr) []Multiaddr { + split, err := bytesSplit(m.Bytes()) + if err != nil { + panic(fmt.Errorf("invalid multiaddr %s", m.String())) + } + + addrs := make([]Multiaddr, len(split)) + for i, addr := range split { + addrs[i] = &multiaddr{bytes: addr} + } + return addrs +} + +// Join returns a combination of addresses. +func Join(ms ...Multiaddr) Multiaddr { + + length := 0 + bs := make([][]byte, len(ms)) + for i, m := range ms { + bs[i] = m.Bytes() + length += len(bs[i]) + } + + bidx := 0 + b := make([]byte, length) + for _, mb := range bs { + for i := range mb { + b[bidx] = mb[i] + bidx++ + } + } + return &multiaddr{bytes: b} +} + +// Cast re-casts a byte slice as a multiaddr. will panic if it fails to parse. +func Cast(b []byte) Multiaddr { + _, err := bytesToString(b) + if err != nil { + panic(fmt.Errorf("multiaddr failed to parse: %s", err)) + } + return &multiaddr{bytes: b} +} + +// StringCast like Cast, but parses a string. Will also panic if it fails to parse. +func StringCast(s string) Multiaddr { + m, err := NewMultiaddr(s) + if err != nil { + panic(fmt.Errorf("multiaddr failed to parse: %s", err)) + } + return m +} diff --git a/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/.travis.yml b/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/.travis.yml new file mode 100644 index 0000000000000000000000000000000000000000..7acdc5f1362d0c99cf5bd38b993b93161c3c0880 --- /dev/null +++ b/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/.travis.yml @@ -0,0 +1,10 @@ +language: go + +go: + - 1.5.1 + +script: + - make test + +env: + - TEST_VERBOSE=1 GO15VENDOREXPERIMENT=1 diff --git a/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/LICENSE b/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..c7386b3c940d8aa7baea2dd6fec2908fed562b89 --- /dev/null +++ b/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Juan Batiz-Benet + +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. + +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. diff --git a/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/Makefile b/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..174b9d89a5803121f3a4e55f29cb403928b1fa73 --- /dev/null +++ b/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/Makefile @@ -0,0 +1,14 @@ +GO15VENDOREXPERIMENT=1 + +all: install + +gx: + go get github.com/whyrusleeping/gx + go get github.com/whyrusleeping/gx-go + +dep: gx + gx install + +test: + go test -race -cpu=5 -v + diff --git a/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/README.md b/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/README.md new file mode 100644 index 0000000000000000000000000000000000000000..1b500814bc4805a5e5cdc57185ffa7fa7be00a76 --- /dev/null +++ b/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/README.md @@ -0,0 +1,11 @@ +# multiaddr/net - Multiaddr friendly net + +Package multiaddr/net provides [Multiaddr](http://github.com/jbenet/go-multiaddr) specific versions of common +functions in stdlib's net package. This means wrappers of +standard net symbols like net.Dial and net.Listen, as well +as conversion to/from net.Addr. + +Docs: + +- `multiaddr/net`: https://godoc.org/github.com/jbenet/go-multiaddr-net +- `multiaddr`: https://godoc.org/github.com/jbenet/go-multiaddr diff --git a/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/convert.go b/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/convert.go new file mode 100644 index 0000000000000000000000000000000000000000..60393e0c2b33c9989102646ab4812714e725cadd --- /dev/null +++ b/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/convert.go @@ -0,0 +1,172 @@ +package manet + +import ( + "fmt" + "net" + "strings" + + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" + utp "QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/utp" +) + +var errIncorrectNetAddr = fmt.Errorf("incorrect network addr conversion") + +// FromNetAddr converts a net.Addr type to a Multiaddr. +func FromNetAddr(a net.Addr) (ma.Multiaddr, error) { + if a == nil { + return nil, fmt.Errorf("nil multiaddr") + } + + switch a.Network() { + case "tcp", "tcp4", "tcp6": + ac, ok := a.(*net.TCPAddr) + if !ok { + return nil, errIncorrectNetAddr + } + + // Get IP Addr + ipm, err := FromIP(ac.IP) + if err != nil { + return nil, errIncorrectNetAddr + } + + // Get TCP Addr + tcpm, err := ma.NewMultiaddr(fmt.Sprintf("/tcp/%d", ac.Port)) + if err != nil { + return nil, errIncorrectNetAddr + } + + // Encapsulate + return ipm.Encapsulate(tcpm), nil + + case "udp", "upd4", "udp6": + ac, ok := a.(*net.UDPAddr) + if !ok { + return nil, errIncorrectNetAddr + } + + // Get IP Addr + ipm, err := FromIP(ac.IP) + if err != nil { + return nil, errIncorrectNetAddr + } + + // Get UDP Addr + udpm, err := ma.NewMultiaddr(fmt.Sprintf("/udp/%d", ac.Port)) + if err != nil { + return nil, errIncorrectNetAddr + } + + // Encapsulate + return ipm.Encapsulate(udpm), nil + + case "utp", "utp4", "utp6": + acc, ok := a.(*utp.Addr) + if !ok { + return nil, errIncorrectNetAddr + } + + // Get UDP Addr + ac, ok := acc.Child().(*net.UDPAddr) + if !ok { + return nil, errIncorrectNetAddr + } + + // Get IP Addr + ipm, err := FromIP(ac.IP) + if err != nil { + return nil, errIncorrectNetAddr + } + + // Get UDP Addr + utpm, err := ma.NewMultiaddr(fmt.Sprintf("/udp/%d/utp", ac.Port)) + if err != nil { + return nil, errIncorrectNetAddr + } + + // Encapsulate + return ipm.Encapsulate(utpm), nil + + case "ip", "ip4", "ip6": + ac, ok := a.(*net.IPAddr) + if !ok { + return nil, errIncorrectNetAddr + } + return FromIP(ac.IP) + + case "ip+net": + ac, ok := a.(*net.IPNet) + if !ok { + return nil, errIncorrectNetAddr + } + return FromIP(ac.IP) + + default: + return nil, fmt.Errorf("unknown network %v", a.Network()) + } +} + +// ToNetAddr converts a Multiaddr to a net.Addr +// Must be ThinWaist. acceptable protocol stacks are: +// /ip{4,6}/{tcp, udp} +func ToNetAddr(maddr ma.Multiaddr) (net.Addr, error) { + network, host, err := DialArgs(maddr) + if err != nil { + return nil, err + } + + switch network { + case "tcp", "tcp4", "tcp6": + return net.ResolveTCPAddr(network, host) + case "udp", "udp4", "udp6": + return net.ResolveUDPAddr(network, host) + case "utp", "utp4", "utp6": + return utp.ResolveAddr(network, host) + case "ip", "ip4", "ip6": + return net.ResolveIPAddr(network, host) + } + + return nil, fmt.Errorf("network not supported: %s", network) +} + +// FromIP converts a net.IP type to a Multiaddr. +func FromIP(ip net.IP) (ma.Multiaddr, error) { + switch { + case ip.To4() != nil: + return ma.NewMultiaddr("/ip4/" + ip.String()) + case ip.To16() != nil: + return ma.NewMultiaddr("/ip6/" + ip.String()) + default: + return nil, errIncorrectNetAddr + } +} + +// DialArgs is a convenience function returning arguments for use in net.Dial +func DialArgs(m ma.Multiaddr) (string, string, error) { + if !IsThinWaist(m) { + return "", "", fmt.Errorf("%s is not a 'thin waist' address", m) + } + + str := m.String() + parts := strings.Split(str, "/")[1:] + + if len(parts) == 2 { // only IP + return parts[0], parts[1], nil + } + + network := parts[2] + if parts[2] == "udp" && len(parts) > 4 && parts[4] == "utp" { + network = parts[4] + } + + var host string + switch parts[0] { + case "ip4": + network = network + "4" + host = strings.Join([]string{parts[1], parts[3]}, ":") + case "ip6": + network = network + "6" + host = fmt.Sprintf("[%s]:%s", parts[1], parts[3]) + } + return network, host, nil +} diff --git a/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/convert_test.go b/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/convert_test.go new file mode 100644 index 0000000000000000000000000000000000000000..838b3c7d3df5aaff53de83cb530f45a361b2ba80 --- /dev/null +++ b/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/convert_test.go @@ -0,0 +1,157 @@ +package manet + +import ( + "net" + "testing" + + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" + mautp "QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/utp" +) + +type GenFunc func() (ma.Multiaddr, error) + +func testConvert(t *testing.T, s string, gen GenFunc) { + m, err := gen() + if err != nil { + t.Fatal("failed to generate.") + } + + if s2 := m.String(); err != nil || s2 != s { + t.Fatal("failed to convert: " + s + " != " + s2) + } +} + +func testToNetAddr(t *testing.T, maddr, ntwk, addr string) { + m, err := ma.NewMultiaddr(maddr) + if err != nil { + t.Fatal("failed to generate.") + } + + naddr, err := ToNetAddr(m) + if addr == "" { // should fail + if err == nil { + t.Fatalf("failed to error: %s", m) + } + return + } + + // shouldn't fail + if err != nil { + t.Fatalf("failed to convert to net addr: %s", m) + } + + if naddr.String() != addr { + t.Fatalf("naddr.Address() == %s != %s", naddr, addr) + } + + if naddr.Network() != ntwk { + t.Fatalf("naddr.Network() == %s != %s", naddr.Network(), ntwk) + } + + // should convert properly + switch ntwk { + case "tcp": + _ = naddr.(*net.TCPAddr) + case "udp": + _ = naddr.(*net.UDPAddr) + case "ip": + _ = naddr.(*net.IPAddr) + } +} + +func TestFromIP4(t *testing.T) { + testConvert(t, "/ip4/10.20.30.40", func() (ma.Multiaddr, error) { + return FromIP(net.ParseIP("10.20.30.40")) + }) +} + +func TestFromIP6(t *testing.T) { + testConvert(t, "/ip6/2001:4860:0:2001::68", func() (ma.Multiaddr, error) { + return FromIP(net.ParseIP("2001:4860:0:2001::68")) + }) +} + +func TestFromTCP(t *testing.T) { + testConvert(t, "/ip4/10.20.30.40/tcp/1234", func() (ma.Multiaddr, error) { + return FromNetAddr(&net.TCPAddr{ + IP: net.ParseIP("10.20.30.40"), + Port: 1234, + }) + }) +} + +func TestFromUDP(t *testing.T) { + testConvert(t, "/ip4/10.20.30.40/udp/1234", func() (ma.Multiaddr, error) { + return FromNetAddr(&net.UDPAddr{ + IP: net.ParseIP("10.20.30.40"), + Port: 1234, + }) + }) +} + +func TestFromUTP(t *testing.T) { + a := &net.UDPAddr{IP: net.ParseIP("10.20.30.40"), Port: 1234} + testConvert(t, "/ip4/10.20.30.40/udp/1234/utp", func() (ma.Multiaddr, error) { + return FromNetAddr(mautp.MakeAddr(a)) + }) +} + +func TestThinWaist(t *testing.T) { + addrs := map[string]bool{ + "/ip4/127.0.0.1/udp/1234": true, + "/ip4/127.0.0.1/tcp/1234": true, + "/ip4/127.0.0.1/udp/1234/utp": true, + "/ip4/127.0.0.1/udp/1234/tcp/1234": true, + "/ip4/127.0.0.1/tcp/12345/ip4/1.2.3.4": true, + "/ip6/::1/tcp/80": true, + "/ip6/::1/udp/80": true, + "/ip6/::1": true, + "/ip6/::1/utp": false, + "/tcp/1234/ip4/1.2.3.4": false, + "/tcp/1234": false, + "/tcp/1234/utp": false, + "/tcp/1234/udp/1234": false, + "/ip4/1.2.3.4/ip4/2.3.4.5": true, + "/ip6/::1/ip4/2.3.4.5": true, + } + + for a, res := range addrs { + m, err := ma.NewMultiaddr(a) + if err != nil { + t.Fatalf("failed to construct Multiaddr: %s", a) + } + + if IsThinWaist(m) != res { + t.Fatalf("IsThinWaist(%s) != %v", a, res) + } + } +} + +func TestDialArgs(t *testing.T) { + test := func(e_maddr, e_nw, e_host string) { + m, err := ma.NewMultiaddr(e_maddr) + if err != nil { + t.Fatal("failed to construct", "/ip4/127.0.0.1/udp/1234", e_maddr) + } + + nw, host, err := DialArgs(m) + if err != nil { + t.Fatal("failed to get dial args", e_maddr, m, err) + } + + if nw != e_nw { + t.Error("failed to get udp network Dial Arg", e_nw, nw) + } + + if host != e_host { + t.Error("failed to get host:port Dial Arg", e_host, host) + } + } + + test("/ip4/127.0.0.1/udp/1234", "udp4", "127.0.0.1:1234") + test("/ip4/127.0.0.1/tcp/4321", "tcp4", "127.0.0.1:4321") + test("/ip4/127.0.0.1/udp/1234/utp", "utp4", "127.0.0.1:1234") + test("/ip6/::1/udp/1234", "udp6", "[::1]:1234") + test("/ip6/::1/tcp/4321", "tcp6", "[::1]:4321") + test("/ip6/::1/udp/1234/utp", "utp6", "[::1]:1234") +} diff --git a/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/doc.go b/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/doc.go new file mode 100644 index 0000000000000000000000000000000000000000..040ad3f02fa6cd98f7b14d9499e341eee85f9c94 --- /dev/null +++ b/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/doc.go @@ -0,0 +1,5 @@ +// Package manet provides Multiaddr specific versions of common +// functions in stdlib's net package. This means wrappers of +// standard net symbols like net.Dial and net.Listen, as well +// as conversion to/from net.Addr. +package manet diff --git a/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/ip.go b/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/ip.go new file mode 100644 index 0000000000000000000000000000000000000000..8aa276a44d5af492dd995c553330e4d5ae6553b1 --- /dev/null +++ b/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/ip.go @@ -0,0 +1,85 @@ +package manet + +import ( + "bytes" + + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" +) + +// Loopback Addresses +var ( + // IP4Loopback is the ip4 loopback multiaddr + IP4Loopback = ma.StringCast("/ip4/127.0.0.1") + + // IP6Loopback is the ip6 loopback multiaddr + IP6Loopback = ma.StringCast("/ip6/::1") + + // IP6LinkLocalLoopback is the ip6 link-local loopback multiaddr + IP6LinkLocalLoopback = ma.StringCast("/ip6/fe80::1") +) + +// Unspecified Addresses (used for ) +var ( + IP4Unspecified = ma.StringCast("/ip4/0.0.0.0") + IP6Unspecified = ma.StringCast("/ip6/::") +) + +// IsThinWaist returns whether a Multiaddr starts with "Thin Waist" Protocols. +// This means: /{IP4, IP6}[/{TCP, UDP}] +func IsThinWaist(m ma.Multiaddr) bool { + p := m.Protocols() + + // nothing? not even a waist. + if len(p) == 0 { + return false + } + + if p[0].Code != ma.P_IP4 && p[0].Code != ma.P_IP6 { + return false + } + + // only IP? still counts. + if len(p) == 1 { + return true + } + + switch p[1].Code { + case ma.P_TCP, ma.P_UDP, ma.P_IP4, ma.P_IP6: + return true + default: + return false + } +} + +// IsIPLoopback returns whether a Multiaddr is a "Loopback" IP address +// This means either /ip4/127.0.0.1 or /ip6/::1 +// TODO: differentiate IsIPLoopback and OverIPLoopback +func IsIPLoopback(m ma.Multiaddr) bool { + b := m.Bytes() + + // /ip4/127 prefix (_entire_ /8 is loopback...) + if bytes.HasPrefix(b, []byte{ma.P_IP4, 127}) { + return true + } + + // /ip6/::1 + if IP6Loopback.Equal(m) || IP6LinkLocalLoopback.Equal(m) { + return true + } + + return false +} + +// IP6 Link Local addresses are non routable. The prefix is technically +// fe80::/10, but we test fe80::/16 for simplicity (no need to mask). +// So far, no hardware interfaces exist long enough to use those 2 bits. +// Send a PR if there is. +func IsIP6LinkLocal(m ma.Multiaddr) bool { + return bytes.HasPrefix(m.Bytes(), []byte{ma.P_IP6, 0xfe, 0x80}) +} + +// IsIPUnspecified returns whether a Multiaddr is am Unspecified IP address +// This means either /ip4/0.0.0.0 or /ip6/:: +func IsIPUnspecified(m ma.Multiaddr) bool { + return IP4Unspecified.Equal(m) || IP6Unspecified.Equal(m) +} diff --git a/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/multiaddr/.gitignore b/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/multiaddr/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e4dcb09f336446a6a162fd5e2002da2349ee7f50 --- /dev/null +++ b/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/multiaddr/.gitignore @@ -0,0 +1 @@ +multiaddr diff --git a/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/multiaddr/multiaddr.go b/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/multiaddr/multiaddr.go new file mode 100644 index 0000000000000000000000000000000000000000..242466cf59c292fbfe04927d329b10470b40dc0d --- /dev/null +++ b/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/multiaddr/multiaddr.go @@ -0,0 +1,96 @@ +package main + +import ( + "encoding/hex" + "flag" + "fmt" + "os" + + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" + manet "QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net" +) + +// flags +var formats = []string{"string", "bytes", "hex", "slice"} +var format string +var hideLoopback bool + +func init() { + flag.Usage = func() { + fmt.Fprintf(os.Stderr, "usage: %s []\n\nFlags:\n", os.Args[0]) + flag.PrintDefaults() + } + + usage := fmt.Sprintf("output format, one of: %v", formats) + flag.StringVar(&format, "format", "string", usage) + flag.StringVar(&format, "f", "string", usage+" (shorthand)") + flag.BoolVar(&hideLoopback, "hide-loopback", false, "do not display loopback addresses") +} + +func main() { + flag.Parse() + args := flag.Args() + if len(args) == 0 { + output(localAddresses()...) + } else { + output(address(args[0])) + } +} + +func localAddresses() []ma.Multiaddr { + maddrs, err := manet.InterfaceMultiaddrs() + if err != nil { + die(err) + } + + if !hideLoopback { + return maddrs + } + + var maddrs2 []ma.Multiaddr + for _, a := range maddrs { + if !manet.IsIPLoopback(a) { + maddrs2 = append(maddrs2, a) + } + } + + return maddrs2 +} + +func address(addr string) ma.Multiaddr { + m, err := ma.NewMultiaddr(addr) + if err != nil { + die(err) + } + + return m +} + +func output(ms ...ma.Multiaddr) { + for _, m := range ms { + fmt.Println(outfmt(m)) + } +} + +func outfmt(m ma.Multiaddr) string { + switch format { + case "string": + return m.String() + case "slice": + return fmt.Sprintf("%v", m.Bytes()) + case "bytes": + return string(m.Bytes()) + case "hex": + return "0x" + hex.EncodeToString(m.Bytes()) + } + + die("error: invalid format", format) + return "" +} + +func die(v ...interface{}) { + fmt.Fprint(os.Stderr, v...) + fmt.Fprint(os.Stderr, "\n") + flag.Usage() + os.Exit(-1) +} diff --git a/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/net.go b/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/net.go new file mode 100644 index 0000000000000000000000000000000000000000..217dfd9db1c34b7aac332b81873795e100ac35f8 --- /dev/null +++ b/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/net.go @@ -0,0 +1,298 @@ +package manet + +import ( + "fmt" + "net" + + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" + mautp "QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/utp" +) + +// Conn is the equivalent of a net.Conn object. It is the +// result of calling the Dial or Listen functions in this +// package, with associated local and remote Multiaddrs. +type Conn interface { + net.Conn + + // LocalMultiaddr returns the local Multiaddr associated + // with this connection + LocalMultiaddr() ma.Multiaddr + + // RemoteMultiaddr returns the remote Multiaddr associated + // with this connection + RemoteMultiaddr() ma.Multiaddr +} + +// WrapNetConn wraps a net.Conn object with a Multiaddr +// friendly Conn. +func WrapNetConn(nconn net.Conn) (Conn, error) { + if nconn == nil { + return nil, fmt.Errorf("failed to convert nconn.LocalAddr: nil") + } + + laddr, err := FromNetAddr(nconn.LocalAddr()) + if err != nil { + return nil, fmt.Errorf("failed to convert nconn.LocalAddr: %s", err) + } + + raddr, err := FromNetAddr(nconn.RemoteAddr()) + if err != nil { + return nil, fmt.Errorf("failed to convert nconn.RemoteAddr: %s", err) + } + + return &maConn{ + Conn: nconn, + laddr: laddr, + raddr: raddr, + }, nil +} + +// maConn implements the Conn interface. It's a thin wrapper +// around a net.Conn +type maConn struct { + net.Conn + laddr ma.Multiaddr + raddr ma.Multiaddr +} + +// LocalMultiaddr returns the local address associated with +// this connection +func (c *maConn) LocalMultiaddr() ma.Multiaddr { + return c.laddr +} + +// RemoteMultiaddr returns the remote address associated with +// this connection +func (c *maConn) RemoteMultiaddr() ma.Multiaddr { + return c.raddr +} + +// Dialer contains options for connecting to an address. It +// is effectively the same as net.Dialer, but its LocalAddr +// and RemoteAddr options are Multiaddrs, instead of net.Addrs. +type Dialer struct { + + // Dialer is just an embedded net.Dialer, with all its options. + net.Dialer + + // LocalAddr is the local address to use when dialing an + // address. The address must be of a compatible type for the + // network being dialed. + // If nil, a local address is automatically chosen. + LocalAddr ma.Multiaddr +} + +// Dial connects to a remote address, using the options of the +// Dialer. Dialer uses an underlying net.Dialer to Dial a +// net.Conn, then wraps that in a Conn object (with local and +// remote Multiaddrs). +func (d *Dialer) Dial(remote ma.Multiaddr) (Conn, error) { + + // if a LocalAddr is specified, use it on the embedded dialer. + if d.LocalAddr != nil { + // convert our multiaddr to net.Addr friendly + naddr, err := ToNetAddr(d.LocalAddr) + if err != nil { + return nil, err + } + + // set the dialer's LocalAddr as naddr + d.Dialer.LocalAddr = naddr + } + + // get the net.Dial friendly arguments from the remote addr + rnet, rnaddr, err := DialArgs(remote) + if err != nil { + return nil, err + } + + // ok, Dial! + var nconn net.Conn + switch rnet { + case "tcp", "tcp4", "tcp6", "udp", "udp4", "udp6": + nconn, err = d.Dialer.Dial(rnet, rnaddr) + if err != nil { + return nil, err + } + case "utp", "utp4", "utp6": + utpd := mautp.Dialer{ + Timeout: d.Timeout, + LocalAddr: d.Dialer.LocalAddr, + } + // construct utp dialer, with options on our net.Dialer + nconn, err = utpd.Dial(rnet, rnaddr) + if err != nil { + return nil, err + } + } + + // get local address (pre-specified or assigned within net.Conn) + local := d.LocalAddr + if local == nil { + local, err = FromNetAddr(nconn.LocalAddr()) + if err != nil { + return nil, err + } + } + + return &maConn{ + Conn: nconn, + laddr: local, + raddr: remote, + }, nil +} + +// Dial connects to a remote address. It uses an underlying net.Conn, +// then wraps it in a Conn object (with local and remote Multiaddrs). +func Dial(remote ma.Multiaddr) (Conn, error) { + return (&Dialer{}).Dial(remote) +} + +// A Listener is a generic network listener for stream-oriented protocols. +// it uses an embedded net.Listener, overriding net.Listener.Accept to +// return a Conn and providing Multiaddr. +type Listener interface { + + // NetListener returns the embedded net.Listener. Use with caution. + NetListener() net.Listener + + // Accept waits for and returns the next connection to the listener. + // Returns a Multiaddr friendly Conn + Accept() (Conn, error) + + // Close closes the listener. + // Any blocked Accept operations will be unblocked and return errors. + Close() error + + // Multiaddr returns the listener's (local) Multiaddr. + Multiaddr() ma.Multiaddr + + // Addr returns the net.Listener's network address. + Addr() net.Addr +} + +// maListener implements Listener +type maListener struct { + net.Listener + laddr ma.Multiaddr +} + +// NetListener returns the embedded net.Listener. Use with caution. +func (l *maListener) NetListener() net.Listener { + return l.Listener +} + +// Accept waits for and returns the next connection to the listener. +// Returns a Multiaddr friendly Conn +func (l *maListener) Accept() (Conn, error) { + nconn, err := l.Listener.Accept() + if err != nil { + return nil, err + } + + raddr, err := FromNetAddr(nconn.RemoteAddr()) + if err != nil { + return nil, fmt.Errorf("failed to convert connn.RemoteAddr: %s", err) + } + + return &maConn{ + Conn: nconn, + laddr: l.laddr, + raddr: raddr, + }, nil +} + +// Multiaddr returns the listener's (local) Multiaddr. +func (l *maListener) Multiaddr() ma.Multiaddr { + return l.laddr +} + +// Addr returns the listener's network address. +func (l *maListener) Addr() net.Addr { + return l.Listener.Addr() +} + +// Listen announces on the local network address laddr. +// The Multiaddr must be a "ThinWaist" stream-oriented network: +// ip4/tcp, ip6/tcp, (TODO: unix, unixpacket) +// See Dial for the syntax of laddr. +func Listen(laddr ma.Multiaddr) (Listener, error) { + + // get the net.Listen friendly arguments from the remote addr + lnet, lnaddr, err := DialArgs(laddr) + if err != nil { + return nil, err + } + + var nl net.Listener + switch lnet { + case "utp", "utp4", "utp6": + nl, err = mautp.Listen(lnet, lnaddr) + default: + nl, err = net.Listen(lnet, lnaddr) + } + if err != nil { + return nil, err + } + + // we want to fetch the new multiaddr from the listener, as it may + // have resolved to some other value. WrapNetListener does it for us. + return WrapNetListener(nl) +} + +// WrapNetListener wraps a net.Listener with a manet.Listener. +func WrapNetListener(nl net.Listener) (Listener, error) { + laddr, err := FromNetAddr(nl.Addr()) + if err != nil { + return nil, err + } + + return &maListener{ + Listener: nl, + laddr: laddr, + }, nil +} + +// InterfaceMultiaddrs will return the addresses matching net.InterfaceAddrs +func InterfaceMultiaddrs() ([]ma.Multiaddr, error) { + addrs, err := net.InterfaceAddrs() + if err != nil { + return nil, err + } + + maddrs := make([]ma.Multiaddr, len(addrs)) + for i, a := range addrs { + maddrs[i], err = FromNetAddr(a) + if err != nil { + return nil, err + } + } + return maddrs, nil +} + +// AddrMatch returns the Multiaddrs that match the protocol stack on addr +func AddrMatch(match ma.Multiaddr, addrs []ma.Multiaddr) []ma.Multiaddr { + + // we should match transports entirely. + p1s := match.Protocols() + + out := make([]ma.Multiaddr, 0, len(addrs)) + for _, a := range addrs { + p2s := a.Protocols() + if len(p1s) != len(p2s) { + continue + } + + match := true + for i, p2 := range p2s { + if p1s[i].Code != p2.Code { + match = false + break + } + } + if match { + out = append(out, a) + } + } + return out +} diff --git a/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/net_test.go b/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/net_test.go new file mode 100644 index 0000000000000000000000000000000000000000..ceaff1876d634c9d69820497f455454976751957 --- /dev/null +++ b/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/net_test.go @@ -0,0 +1,507 @@ +package manet + +import ( + "bytes" + "fmt" + "net" + "sync" + "testing" + + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" +) + +func newMultiaddr(t *testing.T, m string) ma.Multiaddr { + maddr, err := ma.NewMultiaddr(m) + if err != nil { + t.Fatal("failed to construct multiaddr:", m, err) + } + return maddr +} + +func TestDial(t *testing.T) { + + listener, err := net.Listen("tcp", "127.0.0.1:4321") + if err != nil { + t.Fatal("failed to listen") + } + + var wg sync.WaitGroup + wg.Add(1) + go func() { + + cB, err := listener.Accept() + if err != nil { + t.Fatal("failed to accept") + } + + // echo out + buf := make([]byte, 1024) + for { + _, err := cB.Read(buf) + if err != nil { + break + } + cB.Write(buf) + } + + wg.Done() + }() + + maddr := newMultiaddr(t, "/ip4/127.0.0.1/tcp/4321") + cA, err := Dial(maddr) + if err != nil { + t.Fatal("failed to dial") + } + + buf := make([]byte, 1024) + if _, err := cA.Write([]byte("beep boop")); err != nil { + t.Fatal("failed to write:", err) + } + + if _, err := cA.Read(buf); err != nil { + t.Fatal("failed to read:", buf, err) + } + + if !bytes.Equal(buf[:9], []byte("beep boop")) { + t.Fatal("failed to echo:", buf) + } + + maddr2 := cA.RemoteMultiaddr() + if !maddr2.Equal(maddr) { + t.Fatal("remote multiaddr not equal:", maddr, maddr2) + } + + cA.Close() + wg.Wait() +} + +func TestListen(t *testing.T) { + + maddr := newMultiaddr(t, "/ip4/127.0.0.1/tcp/4322") + listener, err := Listen(maddr) + if err != nil { + t.Fatal("failed to listen") + } + + var wg sync.WaitGroup + wg.Add(1) + go func() { + + cB, err := listener.Accept() + if err != nil { + t.Fatal("failed to accept") + } + + if !cB.LocalMultiaddr().Equal(maddr) { + t.Fatal("local multiaddr not equal:", maddr, cB.LocalMultiaddr()) + } + + // echo out + buf := make([]byte, 1024) + for { + _, err := cB.Read(buf) + if err != nil { + break + } + cB.Write(buf) + } + + wg.Done() + }() + + cA, err := net.Dial("tcp", "127.0.0.1:4322") + if err != nil { + t.Fatal("failed to dial") + } + + buf := make([]byte, 1024) + if _, err := cA.Write([]byte("beep boop")); err != nil { + t.Fatal("failed to write:", err) + } + + if _, err := cA.Read(buf); err != nil { + t.Fatal("failed to read:", buf, err) + } + + if !bytes.Equal(buf[:9], []byte("beep boop")) { + t.Fatal("failed to echo:", buf) + } + + maddr2, err := FromNetAddr(cA.RemoteAddr()) + if err != nil { + t.Fatal("failed to convert", err) + } + if !maddr2.Equal(maddr) { + t.Fatal("remote multiaddr not equal:", maddr, maddr2) + } + + cA.Close() + wg.Wait() +} + +func TestListenAddrs(t *testing.T) { + + test := func(addr, resaddr string, succeed bool) { + if resaddr == "" { + resaddr = addr + } + + maddr := newMultiaddr(t, addr) + l, err := Listen(maddr) + if !succeed { + if err == nil { + t.Fatal("succeeded in listening", addr) + } + return + } + if succeed && err != nil { + t.Error("failed to listen", addr, err) + } + if l == nil { + t.Error("failed to listen", addr, succeed, err) + } + if l.Multiaddr().String() != resaddr { + t.Error("listen addr did not resolve properly", l.Multiaddr().String(), resaddr, succeed, err) + } + + if err = l.Close(); err != nil { + t.Fatal("failed to close listener", addr, err) + } + } + + test("/ip4/127.0.0.1/tcp/4324", "", true) + test("/ip4/127.0.0.1/udp/4325", "", false) + test("/ip4/127.0.0.1/udp/4326/udt", "", false) + test("/ip4/0.0.0.0/tcp/4324", "", true) + test("/ip4/0.0.0.0/udp/4325", "", false) + test("/ip4/0.0.0.0/udp/4326/udt", "", false) + test("/ip6/::1/tcp/4324", "", true) + test("/ip6/::1/udp/4325", "", false) + test("/ip6/::1/udp/4326/udt", "", false) + test("/ip6/::/tcp/4324", "", true) + test("/ip6/::/udp/4325", "", false) + test("/ip6/::/udp/4326/udt", "", false) + // test("/ip4/127.0.0.1/udp/4326/utp", true) +} + +func TestListenAndDial(t *testing.T) { + + maddr := newMultiaddr(t, "/ip4/127.0.0.1/tcp/4323") + listener, err := Listen(maddr) + if err != nil { + t.Fatal("failed to listen") + } + + var wg sync.WaitGroup + wg.Add(1) + go func() { + + cB, err := listener.Accept() + if err != nil { + t.Fatal("failed to accept") + } + + if !cB.LocalMultiaddr().Equal(maddr) { + t.Fatal("local multiaddr not equal:", maddr, cB.LocalMultiaddr()) + } + + // echo out + buf := make([]byte, 1024) + for { + _, err := cB.Read(buf) + if err != nil { + break + } + cB.Write(buf) + } + + wg.Done() + }() + + cA, err := Dial(newMultiaddr(t, "/ip4/127.0.0.1/tcp/4323")) + if err != nil { + t.Fatal("failed to dial") + } + + buf := make([]byte, 1024) + if _, err := cA.Write([]byte("beep boop")); err != nil { + t.Fatal("failed to write:", err) + } + + if _, err := cA.Read(buf); err != nil { + t.Fatal("failed to read:", buf, err) + } + + if !bytes.Equal(buf[:9], []byte("beep boop")) { + t.Fatal("failed to echo:", buf) + } + + maddr2 := cA.RemoteMultiaddr() + if !maddr2.Equal(maddr) { + t.Fatal("remote multiaddr not equal:", maddr, maddr2) + } + + cA.Close() + wg.Wait() +} + +func TestListenAndDialUTP(t *testing.T) { + maddr := newMultiaddr(t, "/ip4/127.0.0.1/udp/4323/utp") + listener, err := Listen(maddr) + if err != nil { + t.Fatal("failed to listen: ", err) + } + + var wg sync.WaitGroup + wg.Add(1) + go func() { + + cB, err := listener.Accept() + if err != nil { + t.Fatal("failed to accept") + } + + if !cB.LocalMultiaddr().Equal(maddr) { + t.Fatal("local multiaddr not equal:", maddr, cB.LocalMultiaddr()) + } + + defer cB.Close() + + // echo out + buf := make([]byte, 1024) + for { + _, err := cB.Read(buf) + if err != nil { + break + } + cB.Write(buf) + } + + wg.Done() + }() + + cA, err := Dial(newMultiaddr(t, "/ip4/127.0.0.1/udp/4323/utp")) + if err != nil { + t.Fatal("failed to dial", err) + } + + buf := make([]byte, 1024) + if _, err := cA.Write([]byte("beep boop")); err != nil { + t.Fatal("failed to write:", err) + } + + if _, err := cA.Read(buf); err != nil { + t.Fatal("failed to read:", buf, err) + } + + if !bytes.Equal(buf[:9], []byte("beep boop")) { + t.Fatal("failed to echo:", buf) + } + + maddr2 := cA.RemoteMultiaddr() + if !maddr2.Equal(maddr) { + t.Fatal("remote multiaddr not equal:", maddr, maddr2) + } + + cA.Close() + wg.Wait() +} + +func TestIPLoopback(t *testing.T) { + if IP4Loopback.String() != "/ip4/127.0.0.1" { + t.Error("IP4Loopback incorrect:", IP4Loopback) + } + + if IP6Loopback.String() != "/ip6/::1" { + t.Error("IP6Loopback incorrect:", IP6Loopback) + } + + if IP6LinkLocalLoopback.String() != "/ip6/fe80::1" { + t.Error("IP6LinkLocalLoopback incorrect:", IP6Loopback) + } + + if !IsIPLoopback(IP4Loopback) { + t.Error("IsIPLoopback failed (IP4Loopback)") + } + + if !IsIPLoopback(IP6Loopback) { + t.Error("IsIPLoopback failed (IP6Loopback)") + } + + if !IsIPLoopback(IP6LinkLocalLoopback) { + t.Error("IsIPLoopback failed (IP6LinkLocalLoopback)") + } +} + +func TestIPUnspecified(t *testing.T) { + if IP4Unspecified.String() != "/ip4/0.0.0.0" { + t.Error("IP4Unspecified incorrect:", IP4Unspecified) + } + + if IP6Unspecified.String() != "/ip6/::" { + t.Error("IP6Unspecified incorrect:", IP6Unspecified) + } + + if !IsIPUnspecified(IP4Unspecified) { + t.Error("IsIPUnspecified failed (IP4Unspecified)") + } + + if !IsIPUnspecified(IP6Unspecified) { + t.Error("IsIPUnspecified failed (IP6Unspecified)") + } +} + +func TestIP6LinkLocal(t *testing.T) { + if !IsIP6LinkLocal(IP6LinkLocalLoopback) { + t.Error("IsIP6LinkLocal failed (IP6LinkLocalLoopback)") + } + + for a := 0; a < 65536; a++ { + isLinkLocal := (a == 0xfe80) + m := newMultiaddr(t, fmt.Sprintf("/ip6/%x::1", a)) + if IsIP6LinkLocal(m) != isLinkLocal { + t.Error("IsIP6LinkLocal failed (%s != %v)", m, isLinkLocal) + } + } +} + +func TestConvertNetAddr(t *testing.T) { + m1 := newMultiaddr(t, "/ip4/1.2.3.4/tcp/4001") + + n1, err := ToNetAddr(m1) + if err != nil { + t.Fatal(err) + } + + m2, err := FromNetAddr(n1) + if err != nil { + t.Fatal(err) + } + + if m1.String() != m2.String() { + t.Fatal("ToNetAddr + FromNetAddr did not work") + } +} + +func TestWrapNetConn(t *testing.T) { + // test WrapNetConn nil + if _, err := WrapNetConn(nil); err == nil { + t.Error("WrapNetConn(nil) should return an error") + } + + checkErr := func(err error, s string) { + if err != nil { + t.Fatal(s, err) + } + } + + listener, err := net.Listen("tcp", "127.0.0.1:0") + checkErr(err, "failed to listen") + + var wg sync.WaitGroup + defer wg.Wait() + wg.Add(1) + go func() { + defer wg.Done() + cB, err := listener.Accept() + checkErr(err, "failed to accept") + cB.Close() + }() + + cA, err := net.Dial("tcp", listener.Addr().String()) + checkErr(err, "failed to dial") + defer cA.Close() + + lmaddr, err := FromNetAddr(cA.LocalAddr()) + checkErr(err, "failed to get local addr") + rmaddr, err := FromNetAddr(cA.RemoteAddr()) + checkErr(err, "failed to get remote addr") + + mcA, err := WrapNetConn(cA) + checkErr(err, "failed to wrap conn") + + if mcA.LocalAddr().String() != cA.LocalAddr().String() { + t.Error("wrapped conn local addr differs") + } + if mcA.RemoteAddr().String() != cA.RemoteAddr().String() { + t.Error("wrapped conn remote addr differs") + } + if mcA.LocalMultiaddr().String() != lmaddr.String() { + t.Error("wrapped conn local maddr differs") + } + if mcA.RemoteMultiaddr().String() != rmaddr.String() { + t.Error("wrapped conn remote maddr differs") + } +} + +func TestAddrMatch(t *testing.T) { + + test := func(m ma.Multiaddr, input, expect []ma.Multiaddr) { + actual := AddrMatch(m, input) + testSliceEqual(t, expect, actual) + } + + a := []ma.Multiaddr{ + newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234"), + newMultiaddr(t, "/ip4/1.2.3.4/tcp/2345"), + newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234/tcp/2345"), + newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234/tcp/2345"), + newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234/udp/1234"), + newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234/udp/1234"), + newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234/ip6/::1"), + newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234/ip6/::1"), + newMultiaddr(t, "/ip6/::1/tcp/1234"), + newMultiaddr(t, "/ip6/::1/tcp/2345"), + newMultiaddr(t, "/ip6/::1/tcp/1234/tcp/2345"), + newMultiaddr(t, "/ip6/::1/tcp/1234/tcp/2345"), + newMultiaddr(t, "/ip6/::1/tcp/1234/udp/1234"), + newMultiaddr(t, "/ip6/::1/tcp/1234/udp/1234"), + newMultiaddr(t, "/ip6/::1/tcp/1234/ip6/::1"), + newMultiaddr(t, "/ip6/::1/tcp/1234/ip6/::1"), + } + + test(a[0], a, []ma.Multiaddr{ + newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234"), + newMultiaddr(t, "/ip4/1.2.3.4/tcp/2345"), + }) + test(a[2], a, []ma.Multiaddr{ + newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234/tcp/2345"), + newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234/tcp/2345"), + }) + test(a[4], a, []ma.Multiaddr{ + newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234/udp/1234"), + newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234/udp/1234"), + }) + test(a[6], a, []ma.Multiaddr{ + newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234/ip6/::1"), + newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234/ip6/::1"), + }) + test(a[8], a, []ma.Multiaddr{ + newMultiaddr(t, "/ip6/::1/tcp/1234"), + newMultiaddr(t, "/ip6/::1/tcp/2345"), + }) + test(a[10], a, []ma.Multiaddr{ + newMultiaddr(t, "/ip6/::1/tcp/1234/tcp/2345"), + newMultiaddr(t, "/ip6/::1/tcp/1234/tcp/2345"), + }) + test(a[12], a, []ma.Multiaddr{ + newMultiaddr(t, "/ip6/::1/tcp/1234/udp/1234"), + newMultiaddr(t, "/ip6/::1/tcp/1234/udp/1234"), + }) + test(a[14], a, []ma.Multiaddr{ + newMultiaddr(t, "/ip6/::1/tcp/1234/ip6/::1"), + newMultiaddr(t, "/ip6/::1/tcp/1234/ip6/::1"), + }) + +} + +func testSliceEqual(t *testing.T, a, b []ma.Multiaddr) { + if len(a) != len(b) { + t.Error("differ", a, b) + } + for i, addrA := range a { + if !addrA.Equal(b[i]) { + t.Error("differ", a, b) + } + } +} diff --git a/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/package.json b/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/package.json new file mode 100644 index 0000000000000000000000000000000000000000..c62228325718c5718e42bda6b45f80d89ab2d071 --- /dev/null +++ b/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/package.json @@ -0,0 +1,26 @@ +{ + "name": "go-multiaddr-net", + "author": "whyrusleeping", + "version": "1.0.0", + "gxDependencies": [ + { + "name": "go-utp", + "hash": "QmVBEPpwYNGb5xQW6jPzYgV86KSPRrzhe4hA7o7mtAHZsT", + "version": "1.0.0" + }, + { + "name": "go-multiaddr", + "hash": "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF", + "version": "1.0.0" + }, + { + "name": "go-multihash", + "hash": "QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy", + "version": "1.0.0" + } + ], + "language": "go", + "gx": { + "dvcsimport": "github.com/jbenet/go-multiaddr-net" + } +} \ No newline at end of file diff --git a/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/utp/utp_util.go b/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/utp/utp_util.go new file mode 100644 index 0000000000000000000000000000000000000000..9dd2fb30fd562a01e9e0e9c68d6759f22ba4bbaa --- /dev/null +++ b/vendor/QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr/go-multiaddr-net/utp/utp_util.go @@ -0,0 +1,105 @@ +package utp + +import ( + "errors" + "net" + "time" + + utp "QmVBEPpwYNGb5xQW6jPzYgV86KSPRrzhe4hA7o7mtAHZsT/go-utp" +) + +type Listener struct { + *utp.Socket +} + +type Conn struct { + net.Conn +} + +type Addr struct { + net string + child net.Addr +} + +func (ca *Addr) Network() string { + return ca.net +} + +func (ca *Addr) String() string { + return ca.child.String() +} + +func (ca *Addr) Child() net.Addr { + return ca.child +} + +func MakeAddr(a net.Addr) net.Addr { + return &Addr{ + net: "utp", + child: a, + } +} + +func ResolveAddr(network string, host string) (net.Addr, error) { + a, err := net.ResolveUDPAddr("udp"+network[3:], host) + if err != nil { + return nil, err + } + + return MakeAddr(a), nil +} + +func (u *Conn) LocalAddr() net.Addr { + return MakeAddr(u.Conn.LocalAddr()) +} + +func (u *Conn) RemoteAddr() net.Addr { + return MakeAddr(u.Conn.RemoteAddr()) +} + +func Listen(network string, laddr string) (net.Listener, error) { + switch network { + case "utp", "utp4", "utp6": + s, err := utp.NewSocket("udp"+network[3:], laddr) + if err != nil { + return nil, err + } + + return &Listener{s}, nil + + default: + return nil, errors.New("unrecognized network: " + network) + } +} + +func (u *Listener) Accept() (net.Conn, error) { + c, err := u.Socket.Accept() + if err != nil { + return nil, err + } + + return &Conn{c}, nil +} + +func (u *Listener) Addr() net.Addr { + return MakeAddr(u.Socket.Addr()) +} + +type Dialer struct { + Timeout time.Duration + LocalAddr net.Addr +} + +func (d *Dialer) Dial(rnet string, raddr string) (net.Conn, error) { + if d.LocalAddr != nil { + s, err := utp.NewSocket(d.LocalAddr.Network(), d.LocalAddr.String()) + if err != nil { + return nil, err + } + + // zero timeout is the same as calling s.Dial() + return s.DialTimeout(raddr, d.Timeout) + } + + return utp.DialTimeout(raddr, d.Timeout) +} diff --git a/vendor/QmbDXAJ4Fzpmqw9kTVPtPGZEsgyn33ipbUQEe8vMUZLnTS/jitter/jitter.go b/vendor/QmbDXAJ4Fzpmqw9kTVPtPGZEsgyn33ipbUQEe8vMUZLnTS/jitter/jitter.go new file mode 100644 index 0000000000000000000000000000000000000000..7f0f39b8fe0d3c6f24fc668a988c8d580f24af59 --- /dev/null +++ b/vendor/QmbDXAJ4Fzpmqw9kTVPtPGZEsgyn33ipbUQEe8vMUZLnTS/jitter/jitter.go @@ -0,0 +1,12 @@ +package jitter + +import ( + "math/rand" + "time" +) + +func Duration(average, plusMinus time.Duration) (ret time.Duration) { + ret = average - plusMinus + ret += time.Duration(rand.Int63n(2*int64(plusMinus) + 1)) + return +} diff --git a/vendor/QmbDXAJ4Fzpmqw9kTVPtPGZEsgyn33ipbUQEe8vMUZLnTS/jitter/jitter_test.go b/vendor/QmbDXAJ4Fzpmqw9kTVPtPGZEsgyn33ipbUQEe8vMUZLnTS/jitter/jitter_test.go new file mode 100644 index 0000000000000000000000000000000000000000..e59a50fe7fe15376cbfba12d95b991973f1b2dbb --- /dev/null +++ b/vendor/QmbDXAJ4Fzpmqw9kTVPtPGZEsgyn33ipbUQEe8vMUZLnTS/jitter/jitter_test.go @@ -0,0 +1,9 @@ +package jitter + +import "testing" + +func TestZeroDuration(t *testing.T) { + if Duration(0, 0) != 0 { + t.FailNow() + } +} diff --git a/vendor/QmbDXAJ4Fzpmqw9kTVPtPGZEsgyn33ipbUQEe8vMUZLnTS/jitter/package.json b/vendor/QmbDXAJ4Fzpmqw9kTVPtPGZEsgyn33ipbUQEe8vMUZLnTS/jitter/package.json new file mode 100644 index 0000000000000000000000000000000000000000..1f88cf71e0ea7144b75fc9533c6758cb25d79f13 --- /dev/null +++ b/vendor/QmbDXAJ4Fzpmqw9kTVPtPGZEsgyn33ipbUQEe8vMUZLnTS/jitter/package.json @@ -0,0 +1,9 @@ +{ + "name": "jitter", + "author": "whyrusleeping", + "version": "1.0.0", + "language": "go", + "gx": { + "dvcsimport": "github.com/anacrolix/jitter" + } +} \ No newline at end of file diff --git a/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/.travis.yml b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/.travis.yml new file mode 100644 index 0000000000000000000000000000000000000000..7725b3095a21e8d251101d4ca5fcdf19e358fb88 --- /dev/null +++ b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/.travis.yml @@ -0,0 +1,11 @@ +language: go + +go: + - 1.3 + - release + - tip + +script: + - make test + +env: TEST_VERBOSE=1 diff --git a/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/LICENSE b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..c7386b3c940d8aa7baea2dd6fec2908fed562b89 --- /dev/null +++ b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Juan Batiz-Benet + +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. + +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. diff --git a/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/Makefile b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..d6e3bf6d65291336faf7e76644d15df975416f37 --- /dev/null +++ b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/Makefile @@ -0,0 +1,11 @@ +test: go_test other_tests + +other_tests: + cd test && make test + +go_test: go_deps + go test -race -cpu=5 -v ./... + +go_deps: + go get golang.org/x/crypto/sha3 + go get github.com/jbenet/go-base58 diff --git a/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/README.md b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/README.md new file mode 100644 index 0000000000000000000000000000000000000000..f891499bdbe5c98f178deaeb034f29698aa032a5 --- /dev/null +++ b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/README.md @@ -0,0 +1,45 @@ +# go-multihash + +![travis](https://travis-ci.org/jbenet/go-multihash.svg) + +[multihash](//github.com/jbenet/multihash) implementation in Go. + +## Example + +```go +package main + +import ( + "encoding/hex" + "fmt" + "github.com/jbenet/go-multihash" +) + +func main() { + // ignores errors for simplicity. + // don't do that at home. + + buf, _ := hex.DecodeString("0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33") + mhbuf, _ := multihash.EncodeName(buf, "sha1"); + mhhex := hex.EncodeToString(mhbuf) + fmt.Printf("hex: %v\n", mhhex); + + o, _ := multihash.Decode(mhbuf); + mhhex = hex.EncodeToString(o.Digest); + fmt.Printf("obj: %v 0x%x %d %s\n", o.Name, o.Code, o.Length, mhhex); +} +``` + +Run [test/foo.go](test/foo.go) + +``` +> cd test/ +> go build +> ./test +hex: 11140beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33 +obj: sha1 0x11 20 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33 +``` + +## License + +MIT diff --git a/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/io.go b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/io.go new file mode 100644 index 0000000000000000000000000000000000000000..cdd234c4b436c17c588cf656dd161b1933354939 --- /dev/null +++ b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/io.go @@ -0,0 +1,79 @@ +package multihash + +import ( + "fmt" + "io" +) + +// Reader is an io.Reader wrapper that exposes a function +// to read a whole multihash, parse it, and return it. +type Reader interface { + io.Reader + + ReadMultihash() (Multihash, error) +} + +// Writer is an io.Writer wrapper that exposes a function +// to write a whole multihash. +type Writer interface { + io.Writer + + WriteMultihash(Multihash) error +} + +// NewReader wraps an io.Reader with a multihash.Reader +func NewReader(r io.Reader) Reader { + return &mhReader{r} +} + +// NewWriter wraps an io.Writer with a multihash.Writer +func NewWriter(w io.Writer) Writer { + return &mhWriter{w} +} + +type mhReader struct { + r io.Reader +} + +func (r *mhReader) Read(buf []byte) (n int, err error) { + return r.r.Read(buf) +} + +func (r *mhReader) ReadMultihash() (Multihash, error) { + mhhdr := make([]byte, 2) + if _, err := io.ReadFull(r.r, mhhdr); err != nil { + return nil, err + } + + // first byte is the algo, the second is the length. + + // (varints someday...) + length := uint(mhhdr[1]) + + if length > 127 { + return nil, fmt.Errorf("varints not yet supported (length is %d)", length) + } + + buf := make([]byte, length+2) + buf[0] = mhhdr[0] + buf[1] = mhhdr[1] + + if _, err := io.ReadFull(r.r, buf[2:]); err != nil { + return nil, err + } + + return Cast(buf) +} + +type mhWriter struct { + w io.Writer +} + +func (w *mhWriter) Write(buf []byte) (n int, err error) { + return w.w.Write(buf) +} + +func (w *mhWriter) WriteMultihash(m Multihash) error { + _, err := w.w.Write([]byte(m)) + return err +} diff --git a/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/io_test.go b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/io_test.go new file mode 100644 index 0000000000000000000000000000000000000000..44da78e1f1e592eb573007482cf8b8eaa75d8b1e --- /dev/null +++ b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/io_test.go @@ -0,0 +1,69 @@ +package multihash + +import ( + "bytes" + "io" + "testing" +) + +func TestReader(t *testing.T) { + + var buf bytes.Buffer + + for _, tc := range testCases { + m, err := tc.Multihash() + if err != nil { + t.Fatal(err) + } + + buf.Write([]byte(m)) + } + + r := NewReader(&buf) + + for _, tc := range testCases { + h, err := tc.Multihash() + if err != nil { + t.Fatal(err) + } + + h2, err := r.ReadMultihash() + if err != nil { + t.Error(err) + continue + } + + if !bytes.Equal(h, h2) { + t.Error("h and h2 should be equal") + } + } +} + +func TestWriter(t *testing.T) { + + var buf bytes.Buffer + w := NewWriter(&buf) + + for _, tc := range testCases { + m, err := tc.Multihash() + if err != nil { + t.Error(err) + continue + } + + if err := w.WriteMultihash(m); err != nil { + t.Error(err) + continue + } + + buf2 := make([]byte, len(m)) + if _, err := io.ReadFull(&buf, buf2); err != nil { + t.Error(err) + continue + } + + if !bytes.Equal(m, buf2) { + t.Error("m and buf2 should be equal") + } + } +} diff --git a/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/multihash.go b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/multihash.go new file mode 100644 index 0000000000000000000000000000000000000000..d990f22fe23db83e444c270284482a552bca6ece --- /dev/null +++ b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/multihash.go @@ -0,0 +1,188 @@ +package multihash + +import ( + "encoding/hex" + "errors" + "fmt" + + b58 "QmNsoHoCVhgXcv1Yg45jtkMgimxorTAN36fV9AQMFXHHAQ/go-base58" +) + +// errors +var ( + ErrUnknownCode = errors.New("unknown multihash code") + ErrTooShort = errors.New("multihash too short. must be > 3 bytes") + ErrTooLong = errors.New("multihash too long. must be < 129 bytes") + ErrLenNotSupported = errors.New("multihash does not yet support digests longer than 127 bytes") +) + +// ErrInconsistentLen is returned when a decoded multihash has an inconsistent length +type ErrInconsistentLen struct { + dm *DecodedMultihash +} + +func (e ErrInconsistentLen) Error() string { + return fmt.Sprintf("multihash length inconsistent: %v", e.dm) +} + +// constants +const ( + SHA1 = 0x11 + SHA2_256 = 0x12 + SHA2_512 = 0x13 + SHA3 = 0x14 + BLAKE2B = 0x40 + BLAKE2S = 0x41 +) + +// Names maps the name of a hash to the code +var Names = map[string]int{ + "sha1": SHA1, + "sha2-256": SHA2_256, + "sha2-512": SHA2_512, + "sha3": SHA3, + "blake2b": BLAKE2B, + "blake2s": BLAKE2S, +} + +// Codes maps a hash code to it's name +var Codes = map[int]string{ + SHA1: "sha1", + SHA2_256: "sha2-256", + SHA2_512: "sha2-512", + SHA3: "sha3", + BLAKE2B: "blake2b", + BLAKE2S: "blake2s", +} + +// DefaultLengths maps a hash code to it's default length +var DefaultLengths = map[int]int{ + SHA1: 20, + SHA2_256: 32, + SHA2_512: 64, + SHA3: 64, + BLAKE2B: 64, + BLAKE2S: 32, +} + +type DecodedMultihash struct { + Code int + Name string + Length int + Digest []byte +} + +type Multihash []byte + +func (m *Multihash) HexString() string { + return hex.EncodeToString([]byte(*m)) +} + +func (m *Multihash) String() string { + return m.HexString() +} + +func FromHexString(s string) (Multihash, error) { + b, err := hex.DecodeString(s) + if err != nil { + return Multihash{}, err + } + + return Cast(b) +} + +func (m Multihash) B58String() string { + return b58.Encode([]byte(m)) +} + +func FromB58String(s string) (m Multihash, err error) { + // panic handler, in case we try accessing bytes incorrectly. + defer func() { + if e := recover(); e != nil { + m = Multihash{} + err = e.(error) + } + }() + + //b58 smells like it can panic... + b := b58.Decode(s) + return Cast(b) +} + +func Cast(buf []byte) (Multihash, error) { + dm, err := Decode(buf) + if err != nil { + return Multihash{}, err + } + + if !ValidCode(dm.Code) { + return Multihash{}, ErrUnknownCode + } + + return Multihash(buf), nil +} + +// Decode a hash from the given Multihash. +func Decode(buf []byte) (*DecodedMultihash, error) { + + if len(buf) < 3 { + return nil, ErrTooShort + } + + if len(buf) > 129 { + return nil, ErrTooLong + } + + dm := &DecodedMultihash{ + Code: int(uint8(buf[0])), + Name: Codes[int(uint8(buf[0]))], + Length: int(uint8(buf[1])), + Digest: buf[2:], + } + + if len(dm.Digest) != dm.Length { + return nil, ErrInconsistentLen{dm} + } + + return dm, nil +} + +// Encode a hash digest along with the specified function code. +// Note: the length is derived from the length of the digest itself. +func Encode(buf []byte, code int) ([]byte, error) { + + if !ValidCode(code) { + return nil, ErrUnknownCode + } + + if len(buf) > 127 { + return nil, ErrLenNotSupported + } + + pre := make([]byte, 2) + pre[0] = byte(uint8(code)) + pre[1] = byte(uint8(len(buf))) + return append(pre, buf...), nil +} + +func EncodeName(buf []byte, name string) ([]byte, error) { + return Encode(buf, Names[name]) +} + +// ValidCode checks whether a multihash code is valid. +func ValidCode(code int) bool { + if AppCode(code) { + return true + } + + if _, ok := Codes[code]; ok { + return true + } + + return false +} + +// AppCode checks whether a multihash code is part of the App range. +func AppCode(code int) bool { + return code >= 0 && code < 0x10 +} diff --git a/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/multihash/.gitignore b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/multihash/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..2826f1799c4f69b1bc03f6613cd8494695a480d2 --- /dev/null +++ b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/multihash/.gitignore @@ -0,0 +1 @@ +multihash diff --git a/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/multihash/.gobuilder.yml b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/multihash/.gobuilder.yml new file mode 100644 index 0000000000000000000000000000000000000000..d775798e97e4a9d62525ae26e3b0ba975e04e1dc --- /dev/null +++ b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/multihash/.gobuilder.yml @@ -0,0 +1,5 @@ +--- +artifacts: + - LICENSE + - README.md + - install.dist.sh diff --git a/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/multihash/LICENSE b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/multihash/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..c7386b3c940d8aa7baea2dd6fec2908fed562b89 --- /dev/null +++ b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/multihash/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Juan Batiz-Benet + +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. + +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. diff --git a/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/multihash/README.md b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/multihash/README.md new file mode 100644 index 0000000000000000000000000000000000000000..491e759e88b8ec734cf00600e3ad6c5bf7cc2201 --- /dev/null +++ b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/multihash/README.md @@ -0,0 +1,118 @@ +# multihash tool + +The `multihash` tool uses `go-multihash` to hash things much like `shasum`. + +Warning: this is a **multihash** tool! Its digests follow the [multihash](https://github.com/jbenet/multihash) format. + +### Install + +- From Source: + ``` + go get github.com/jbenet/go-multihash/multihash + ``` +- Precompiled Binaries: https://gobuilder.me/github.com/jbenet/go-multihash/multihash + +### Usage + +```sh +> multihash -h +usage: ./multihash [options] [FILE] +Print or check multihash checksums. +With no FILE, or when FILE is -, read standard input. + +Options: + -a="sha2-256": one of: sha1, sha2-256, sha2-512, sha3 (shorthand) + -algorithm="sha2-256": one of: sha1, sha2-256, sha2-512, sha3 + -c="": check checksum matches (shorthand) + -check="": check checksum matches + -e="base58": one of: raw, hex, base58, base64 (shorthand) + -encoding="base58": one of: raw, hex, base58, base64 + -l=-1: checksums length in bits (truncate). -1 is default (shorthand) + -length=-1: checksums length in bits (truncate). -1 is default +``` + +### Examples + +#### Input + +```sh +# from stdin +> multihash < main.go +QmRZxt2b1FVZPNqd8hsiykDL3TdBDeTSPX9Kv46HmX4Gx8 + +# from file +> ./multihash main.go +QmRZxt2b1FVZPNqd8hsiykDL3TdBDeTSPX9Kv46HmX4Gx8 + +# from stdin "filename" +> multihash - < main.go +QmRZxt2b1FVZPNqd8hsiykDL3TdBDeTSPX9Kv46HmX4Gx8 +``` + +#### Algorithms + +```sh +> multihash -a ? +error: algorithm '?' not one of: sha1, sha2-256, sha2-512, sha3 + +> multihash -a sha1 < main.go +5drkbcqJUo6fZVvcZJeVEVWAgndvLm + +> multihash -a sha2-256 < main.go +QmcK3s36goo9v2HYcfTrDKKwxaxmJJ59etodQQFYsL5T5N + +> multihash -a sha2-512 < main.go +8VuDcW4CooyPQA8Cc4eYpwjhyDJZqu5m5ZMDFzWULYsVS8d119JaGeNWsZbZ2ZG2kPtbrMx31MidokCigaD65yUPAs + +> multihash -a sha3 < main.go +8tWDCTfAX24DYmzNixTj2ARJkqwRG736VHx5aJppmqRjhW9QT1EuTgKUmu9Pmunzq292jzPKxb2VxSsTXmjFY1HD3B +``` + +#### Encodings + +```sh +> multihash -e raw < main.go + Ϛ�����I�5 S��WG>���_��]g�����u + +> multihash -e hex < main.go +1220cf9aa2b8a38b9b49d135095390059a57473e97aceb5fcae25d67a8b6feb58275 + +> multihash -e base64 < main.go +EiDPmqK4o4ubSdE1CVOQBZpXRz6XrOtfyuJdZ6i2/rWCdQ== + +> multihash -e base58 < main.go +Qmf1QjEXDmqBm7RqHKqFGNUyhzUjnX7cmgKMrGzzPceZDQ +``` + +#### Digest Length + +```sh +# we're outputing hex (good byte alignment) to show the codes changing +# notice the multihash code (first 2 chars) differs! +> multihash -e hex -a sha2-256 -l 256 < main.go +1220cf9aa2b8a38b9b49d135095390059a57473e97aceb5fcae25d67a8b6feb58275 +> multihash -e hex -a sha2-512 -l 256 < main.go +132047a4b6c629f5545f529b0ff461dc09119969f3593186277a1cc7a8ea3560a6f1 +> multihash -e hex -a sha3 -l 256 < main.go +14206b9222a1a47939e665261bd2b5573e55e7988675223adde73c1011066ad66335 + +# notice the multihash length (next 2 chars) differs! +> multihash -e hex -a sha2-256 -l 256 < main.go +1220cf9aa2b8a38b9b49d135095390059a57473e97aceb5fcae25d67a8b6feb58275 +> multihash -e hex -a sha2-256 -l 200 < main.go +1219cf9aa2b8a38b9b49d135095390059a57473e97aceb5fcae25d +``` + +#### Verify Checksum + +```sh +> multihash -c QmRZxt2b1FVZPNqd8hsiykDL3TdBDeTSPX9Kv46HmX4Gx8 < main.go +OK checksums match (-q for no output) + +> multihash -c QmcKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa < main.go +error: computed checksum did not match (-q for no output) + +# works with other arguments too +> multihash -e hex -l 128 -c "12102ffc284a1e82bf51e567c75b2ae6edb9" < main.go +OK checksums match (-q for no output) +``` diff --git a/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/multihash/install.dist.sh b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/multihash/install.dist.sh new file mode 100644 index 0000000000000000000000000000000000000000..f90274f68552b90de80ec4df1496f9e9ffa964e7 --- /dev/null +++ b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/multihash/install.dist.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +bin=multihash + +# this script is currently brain dead. +# it merely tries two locations. +# in the future maybe use value of $PATH. + +binpath=/usr/local/bin +if [ -d "$binpath" ]; then + mv "$bin" "$binpath/$bin" + echo "installed $binpath/$bin" + exit 0 +fi + +binpath=/usr/bin +if [ -d "$binpath" ]; then + mv "$bin" "$binpath/$bin" + echo "installed $binpath/$bin" + exit 0 +fi diff --git a/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/multihash/main.go b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/multihash/main.go new file mode 100644 index 0000000000000000000000000000000000000000..280842a4a3d4a1b52989a3547afc197827c34d6b --- /dev/null +++ b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/multihash/main.go @@ -0,0 +1,132 @@ +package main + +import ( + "flag" + "fmt" + "io" + "os" + + mh "QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash" + mhopts "QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/opts" +) + +var usage = `usage: %s [options] [FILE] +Print or check multihash checksums. +With no FILE, or when FILE is -, read standard input. + +Options: +` + +// flags +var opts *mhopts.Options +var checkRaw string +var checkMh mh.Multihash +var inputFilename string +var quiet bool + +func init() { + flag.Usage = func() { + fmt.Fprintf(os.Stderr, usage, os.Args[0]) + flag.PrintDefaults() + } + + opts = mhopts.SetupFlags(flag.CommandLine) + + checkStr := "check checksum matches" + flag.StringVar(&checkRaw, "check", "", checkStr) + flag.StringVar(&checkRaw, "c", "", checkStr+" (shorthand)") + + quietStr := "quiet output (no newline on checksum, no error text)" + flag.BoolVar(&quiet, "quiet", false, quietStr) + flag.BoolVar(&quiet, "q", false, quietStr+" (shorthand)") +} + +func parseFlags(o *mhopts.Options) error { + flag.Parse() + if err := o.ParseError(); err != nil { + return err + } + + if checkRaw != "" { + var err error + checkMh, err = mhopts.Decode(o.Encoding, checkRaw) + if err != nil { + return fmt.Errorf("fail to decode check '%s': %s", checkRaw, err) + } + } + + return nil +} + +func getInput() (io.ReadCloser, error) { + args := flag.Args() + + switch { + case len(args) < 1: + inputFilename = "-" + return os.Stdin, nil + case args[0] == "-": + inputFilename = "-" + return os.Stdin, nil + default: + inputFilename = args[0] + f, err := os.Open(args[0]) + if err != nil { + return nil, fmt.Errorf("failed to open '%s': %s", args[0], err) + } + return f, nil + } +} +func printHash(o *mhopts.Options, r io.Reader) error { + h, err := o.Multihash(r) + if err != nil { + return err + } + + s, err := mhopts.Encode(o.Encoding, h) + if err != nil { + return err + } + + if quiet { + fmt.Print(s) + } else { + fmt.Println(s) + } + return nil +} + +func main() { + checkErr := func(err error) { + if err != nil { + die("error: ", err) + } + } + + err := parseFlags(opts) + checkErr(err) + + inp, err := getInput() + checkErr(err) + + if checkMh != nil { + err = opts.Check(inp, checkMh) + checkErr(err) + if !quiet { + fmt.Println("OK checksums match (-q for no output)") + } + } else { + err = printHash(opts, inp) + checkErr(err) + } + inp.Close() +} + +func die(v ...interface{}) { + if !quiet { + fmt.Fprint(os.Stderr, v...) + fmt.Fprint(os.Stderr, "\n") + } + // flag.Usage() + os.Exit(1) +} diff --git a/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/multihash_test.go b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/multihash_test.go new file mode 100644 index 0000000000000000000000000000000000000000..dfa858e4f8935f58d7fa15393980c5de5475d1f1 --- /dev/null +++ b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/multihash_test.go @@ -0,0 +1,270 @@ +package multihash + +import ( + "bytes" + "encoding/hex" + "fmt" + "testing" +) + +// maybe silly, but makes it so changing +// the table accidentally has to happen twice. +var tCodes = map[int]string{ + 0x11: "sha1", + 0x12: "sha2-256", + 0x13: "sha2-512", + 0x14: "sha3", + 0x40: "blake2b", + 0x41: "blake2s", +} + +type TestCase struct { + hex string + code int + name string +} + +var testCases = []TestCase{ + TestCase{"0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33", 0x11, "sha1"}, + TestCase{"0beec7b5", 0x11, "sha1"}, + TestCase{"2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae", 0x12, "sha2-256"}, + TestCase{"2c26b46b", 0x12, "sha2-256"}, + TestCase{"0beec7b5ea3f0fdbc9", 0x40, "blake2b"}, +} + +func (tc TestCase) Multihash() (Multihash, error) { + ob, err := hex.DecodeString(tc.hex) + if err != nil { + return nil, err + } + + b := make([]byte, 2+len(ob)) + b[0] = byte(uint8(tc.code)) + b[1] = byte(uint8(len(ob))) + copy(b[2:], ob) + return Cast(b) +} + +func TestEncode(t *testing.T) { + for _, tc := range testCases { + ob, err := hex.DecodeString(tc.hex) + if err != nil { + t.Error(err) + continue + } + + pre := make([]byte, 2) + pre[0] = byte(uint8(tc.code)) + pre[1] = byte(uint8(len(ob))) + nb := append(pre, ob...) + + encC, err := Encode(ob, tc.code) + if err != nil { + t.Error(err) + continue + } + + if !bytes.Equal(encC, nb) { + t.Error("encoded byte mismatch: ", encC, nb) + } + + encN, err := EncodeName(ob, tc.name) + if err != nil { + t.Error(err) + continue + } + + if !bytes.Equal(encN, nb) { + t.Error("encoded byte mismatch: ", encN, nb) + } + + h, err := tc.Multihash() + if err != nil { + t.Error(err) + } + if !bytes.Equal(h, nb) { + t.Error("Multihash func mismatch.") + } + } +} + +func ExampleEncodeName() { + // ignores errors for simplicity - don't do that at home. + buf, _ := hex.DecodeString("0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33") + mhbuf, _ := EncodeName(buf, "sha1") + mhhex := hex.EncodeToString(mhbuf) + fmt.Printf("hex: %v\n", mhhex) + + // Output: + // hex: 11140beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33 +} + +func TestDecode(t *testing.T) { + for _, tc := range testCases { + ob, err := hex.DecodeString(tc.hex) + if err != nil { + t.Error(err) + continue + } + + pre := make([]byte, 2) + pre[0] = byte(uint8(tc.code)) + pre[1] = byte(uint8(len(ob))) + nb := append(pre, ob...) + + dec, err := Decode(nb) + if err != nil { + t.Error(err) + continue + } + + if dec.Code != tc.code { + t.Error("decoded code mismatch: ", dec.Code, tc.code) + } + + if dec.Name != tc.name { + t.Error("decoded name mismatch: ", dec.Name, tc.name) + } + + if dec.Length != len(ob) { + t.Error("decoded length mismatch: ", dec.Length, len(ob)) + } + + if !bytes.Equal(dec.Digest, ob) { + t.Error("decoded byte mismatch: ", dec.Digest, ob) + } + } +} + +func TestTable(t *testing.T) { + for k, v := range tCodes { + if Codes[k] != v { + t.Error("Table mismatch: ", Codes[k], v) + } + if Names[v] != k { + t.Error("Table mismatch: ", Names[v], k) + } + } +} + +func ExampleDecode() { + // ignores errors for simplicity - don't do that at home. + buf, _ := hex.DecodeString("0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33") + mhbuf, _ := EncodeName(buf, "sha1") + o, _ := Decode(mhbuf) + mhhex := hex.EncodeToString(o.Digest) + fmt.Printf("obj: %v 0x%x %d %s\n", o.Name, o.Code, o.Length, mhhex) + + // Output: + // obj: sha1 0x11 20 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33 +} + +func TestValidCode(t *testing.T) { + for i := 0; i < 0xff; i++ { + _, ok := tCodes[i] + b := AppCode(i) || ok + + if ValidCode(i) != b { + t.Error("ValidCode incorrect for: ", i) + } + } +} + +func TestAppCode(t *testing.T) { + for i := 0; i < 0xff; i++ { + b := i >= 0 && i < 0x10 + if AppCode(i) != b { + t.Error("AppCode incorrect for: ", i) + } + } +} + +func TestCast(t *testing.T) { + for _, tc := range testCases { + ob, err := hex.DecodeString(tc.hex) + if err != nil { + t.Error(err) + continue + } + + pre := make([]byte, 2) + pre[0] = byte(uint8(tc.code)) + pre[1] = byte(uint8(len(ob))) + nb := append(pre, ob...) + + if _, err := Cast(nb); err != nil { + t.Error(err) + continue + } + + if _, err = Cast(ob); err == nil { + t.Error("cast failed to detect non-multihash") + continue + } + } +} + +func TestHex(t *testing.T) { + for _, tc := range testCases { + ob, err := hex.DecodeString(tc.hex) + if err != nil { + t.Error(err) + continue + } + + pre := make([]byte, 2) + pre[0] = byte(uint8(tc.code)) + pre[1] = byte(uint8(len(ob))) + nb := append(pre, ob...) + + hs := hex.EncodeToString(nb) + mh, err := FromHexString(hs) + if err != nil { + t.Error(err) + continue + } + + if !bytes.Equal(mh, nb) { + t.Error("FromHexString failed", nb, mh) + continue + } + + if mh.HexString() != hs { + t.Error("Multihash.HexString failed", hs, mh.HexString) + continue + } + } +} + +func BenchmarkEncode(b *testing.B) { + tc := testCases[0] + ob, err := hex.DecodeString(tc.hex) + if err != nil { + b.Error(err) + return + } + + b.ResetTimer() + for i := 0; i < b.N; i++ { + Encode(ob, tc.code) + } +} + +func BenchmarkDecode(b *testing.B) { + tc := testCases[0] + ob, err := hex.DecodeString(tc.hex) + if err != nil { + b.Error(err) + return + } + + pre := make([]byte, 2) + pre[0] = byte(uint8(tc.code)) + pre[1] = byte(uint8(len(ob))) + nb := append(pre, ob...) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + Decode(nb) + } +} diff --git a/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/opts/README.md b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/opts/README.md new file mode 100644 index 0000000000000000000000000000000000000000..231f28329765f663cc234427cd3676752ed13b81 --- /dev/null +++ b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/opts/README.md @@ -0,0 +1,9 @@ +# mhopts - multihash options for writing commands + +`mhopts` is a small package that helps to write commands which +may take multihash options. Check it out in action: + +- [multihash](../multihash) +- [hashpipe](https://github.com/jbenet/go-hashpipe) + +Godoc: [https://godoc.org/github.com/jbenet/go-multihash/opts](https://godoc.org/github.com/jbenet/go-multihash/opts) diff --git a/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/opts/coding.go b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/opts/coding.go new file mode 100644 index 0000000000000000000000000000000000000000..db5604b0cd4284af55c4133b561e48f43a5b7a5f --- /dev/null +++ b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/opts/coding.go @@ -0,0 +1,40 @@ +package opts + +import ( + "encoding/base64" + "encoding/hex" + "fmt" + + base58 "QmNsoHoCVhgXcv1Yg45jtkMgimxorTAN36fV9AQMFXHHAQ/go-base58" + mh "QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash" +) + +func Decode(encoding, digest string) (mh.Multihash, error) { + switch encoding { + case "raw": + return mh.Cast([]byte(digest)) + case "hex": + return hex.DecodeString(digest) + case "base58": + return base58.Decode(digest), nil + case "base64": + return base64.StdEncoding.DecodeString(digest) + default: + return nil, fmt.Errorf("unknown encoding: %s", encoding) + } +} + +func Encode(encoding string, hash mh.Multihash) (string, error) { + switch encoding { + case "raw": + return string(hash), nil + case "hex": + return hex.EncodeToString(hash), nil + case "base58": + return base58.Encode(hash), nil + case "base64": + return base64.StdEncoding.EncodeToString(hash), nil + default: + return "", fmt.Errorf("unknown encoding: %s", encoding) + } +} diff --git a/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/opts/opts.go b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/opts/opts.go new file mode 100644 index 0000000000000000000000000000000000000000..ecfc9bf41bfc896fec2471a335610f69be59ec4a --- /dev/null +++ b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/opts/opts.go @@ -0,0 +1,131 @@ +// Package opts helps to write commands which may take multihash +// options. +package opts + +import ( + "bytes" + "errors" + "flag" + "fmt" + "io" + "io/ioutil" + "strings" + + mh "QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash" +) + +// package errors +var ( + ErrMatch = errors.New("multihash checksums did not match") +) + +// Options is a struct used to parse cli flags. +type Options struct { + Encoding string + Algorithm string + AlgorithmCode int + Length int + + fs *flag.FlagSet +} + +// FlagValues are the values the various option flags can take. +var FlagValues = struct { + Encodings []string + Algorithms []string +}{ + Encodings: []string{"raw", "hex", "base58", "base64"}, + Algorithms: []string{"sha1", "sha2-256", "sha2-512", "sha3"}, +} + +// SetupFlags adds multihash related options to given flagset. +func SetupFlags(f *flag.FlagSet) *Options { + // TODO: add arg for adding opt prefix and/or overriding opts + + o := new(Options) + algoStr := "one of: " + strings.Join(FlagValues.Algorithms, ", ") + f.StringVar(&o.Algorithm, "algorithm", "sha2-256", algoStr) + f.StringVar(&o.Algorithm, "a", "sha2-256", algoStr+" (shorthand)") + + encStr := "one of: " + strings.Join(FlagValues.Encodings, ", ") + f.StringVar(&o.Encoding, "encoding", "base58", encStr) + f.StringVar(&o.Encoding, "e", "base58", encStr+" (shorthand)") + + lengthStr := "checksums length in bits (truncate). -1 is default" + f.IntVar(&o.Length, "length", -1, lengthStr) + f.IntVar(&o.Length, "l", -1, lengthStr+" (shorthand)") + return o +} + +// Parse parses the values of flags from given argument slice. +// It is equivalent to flags.Parse(args) +func (o *Options) Parse(args []string) error { + if err := o.fs.Parse(args); err != nil { + return err + } + return o.ParseError() +} + +// ParseError checks the parsed options for errors. +func (o *Options) ParseError() error { + if !strIn(o.Encoding, FlagValues.Encodings) { + return fmt.Errorf("encoding '%s' not %s", o.Encoding, FlagValues.Encodings) + } + + if !strIn(o.Algorithm, FlagValues.Algorithms) { + return fmt.Errorf("algorithm '%s' not %s", o.Algorithm, FlagValues.Algorithms) + } + + var found bool + o.AlgorithmCode, found = mh.Names[o.Algorithm] + if !found { + return fmt.Errorf("algorithm '%s' not found (lib error, pls report).", o.Algorithm) + } + + if o.Length >= 0 { + if o.Length%8 != 0 { + return fmt.Errorf("length must be multiple of 8") + } + o.Length = o.Length / 8 + + if o.Length > mh.DefaultLengths[o.AlgorithmCode] { + o.Length = mh.DefaultLengths[o.AlgorithmCode] + } + } + return nil +} + +// strIn checks wither string a is in set. +func strIn(a string, set []string) bool { + for _, s := range set { + if s == a { + return true + } + } + return false +} + +// Check reads all the data in r, calculates its multihash, +// and checks it matches h1 +func (o *Options) Check(r io.Reader, h1 mh.Multihash) error { + h2, err := o.Multihash(r) + if err != nil { + return err + } + + if !bytes.Equal(h1, h2) { + return fmt.Errorf("computed checksum did not match") + } + + return nil +} + +// Multihash reads all the data in r and calculates its multihash. +func (o *Options) Multihash(r io.Reader) (mh.Multihash, error) { + b, err := ioutil.ReadAll(r) + if err != nil { + return nil, err + } + + return mh.Sum(b, o.AlgorithmCode, o.Length) +} diff --git a/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/package.json b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/package.json new file mode 100644 index 0000000000000000000000000000000000000000..6c5a3e055474c0b252607d7bb255ffd60c35d398 --- /dev/null +++ b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/package.json @@ -0,0 +1,21 @@ +{ + "name": "go-multihash", + "author": "whyrusleeping", + "version": "1.0.0", + "gxDependencies": [ + { + "name": "go-base58", + "hash": "QmNsoHoCVhgXcv1Yg45jtkMgimxorTAN36fV9AQMFXHHAQ", + "version": "1.0.0" + }, + { + "name": "crypto-sha3", + "hash": "QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb", + "version": "1.0.0" + } + ], + "language": "go", + "gx": { + "dvcsimport": "github.com/jbenet/go-multihash" + } +} \ No newline at end of file diff --git a/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/sum.go b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/sum.go new file mode 100644 index 0000000000000000000000000000000000000000..1c89c1b9e9f442da9b7951ab48aa838d10278d19 --- /dev/null +++ b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/sum.go @@ -0,0 +1,72 @@ +package multihash + +import ( + "crypto/sha1" + "crypto/sha256" + "crypto/sha512" + "errors" + "fmt" + + sha3 "QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb/crypto-sha3" +) + +var ErrSumNotSupported = errors.New("Function not implemented. Complain to lib maintainer.") + +func Sum(data []byte, code int, length int) (Multihash, error) { + m := Multihash{} + err := error(nil) + if !ValidCode(code) { + return m, fmt.Errorf("invalid multihash code %d", code) + } + + var d []byte + switch code { + case SHA1: + d = sumSHA1(data) + case SHA2_256: + d = sumSHA256(data) + case SHA2_512: + d = sumSHA512(data) + case SHA3: + d, err = sumSHA3(data) + default: + return m, ErrSumNotSupported + } + + if err != nil { + return m, err + } + + if length < 0 { + var ok bool + length, ok = DefaultLengths[code] + if !ok { + return m, fmt.Errorf("no default length for code %d", code) + } + } + + return Encode(d[0:length], code) +} + +func sumSHA1(data []byte) []byte { + a := sha1.Sum(data) + return a[0:20] +} + +func sumSHA256(data []byte) []byte { + a := sha256.Sum256(data) + return a[0:32] +} + +func sumSHA512(data []byte) []byte { + a := sha512.Sum512(data) + return a[0:64] +} + +func sumSHA3(data []byte) ([]byte, error) { + h := sha3.New512() + if _, err := h.Write(data); err != nil { + return nil, err + } + return h.Sum(nil), nil +} diff --git a/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/sum_test.go b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/sum_test.go new file mode 100644 index 0000000000000000000000000000000000000000..1e5891bbbf8fd7cafe119090234c85dfb031d973 --- /dev/null +++ b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/sum_test.go @@ -0,0 +1,66 @@ +package multihash + +import ( + "bytes" + "testing" +) + +type SumTestCase struct { + code int + length int + input string + hex string +} + +var sumTestCases = []SumTestCase{ + SumTestCase{SHA1, -1, "foo", "11140beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"}, + SumTestCase{SHA1, 10, "foo", "110a0beec7b5ea3f0fdbc95d"}, + SumTestCase{SHA2_256, -1, "foo", "12202c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"}, + SumTestCase{SHA2_256, 16, "foo", "12102c26b46b68ffc68ff99b453c1d304134"}, + SumTestCase{SHA2_512, -1, "foo", "1340f7fbba6e0636f890e56fbbf3283e524c6fa3204ae298382d624741d0dc6638326e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7"}, + SumTestCase{SHA2_512, 32, "foo", "1320f7fbba6e0636f890e56fbbf3283e524c6fa3204ae298382d624741d0dc663832"}, +} + +func TestSum(t *testing.T) { + + for _, tc := range sumTestCases { + + m1, err := FromHexString(tc.hex) + if err != nil { + t.Error(err) + continue + } + + m2, err := Sum([]byte(tc.input), tc.code, tc.length) + if err != nil { + t.Error(tc.code, "sum failed.", err) + continue + } + + if !bytes.Equal(m1, m2) { + t.Error(tc.code, "sum failed.", m1, m2) + } + + s1 := m1.HexString() + if s1 != tc.hex { + t.Error("hex strings not the same") + } + + s2 := m1.B58String() + m3, err := FromB58String(s2) + if err != nil { + t.Error("failed to decode b58") + } else if !bytes.Equal(m3, m1) { + t.Error("b58 failing bytes") + } else if s2 != m3.B58String() { + t.Error("b58 failing string") + } + } +} + +func BenchmarkSum(b *testing.B) { + tc := sumTestCases[0] + for i := 0; i < b.N; i++ { + Sum([]byte(tc.input), tc.code, tc.length) + } +} diff --git a/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/test/.gitignore b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/test/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..27f75ed6657e215051e6f773da39c3ecf54fe03e --- /dev/null +++ b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/test/.gitignore @@ -0,0 +1 @@ +bin/multihash diff --git a/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/test/Makefile b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/test/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..e9660d0cabe4f94837b6671ed4a4c7a684ee633f --- /dev/null +++ b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/test/Makefile @@ -0,0 +1,25 @@ +BINS = bin/multihash +MULTIHASH_ROOT = ../ +MULTIHASH_CMD = ../multihash + +all: deps + +deps: bins + +clean: + rm $(BINS) + +bins: $(BINS) + +bin/multihash: $(MULTIHASH_ROOT)/**/*.go + go build -o bin/multihash $(MULTIHASH_CMD) + +test: test_expensive + +test_expensive: + cd sharness && make TEST_EXPENSIVE=1 + +test_cheap: + cd sharness && make + +.PHONY: all clean diff --git a/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/test/sharness/.gitignore b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/test/sharness/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..5e59048ac5fe131b42d6abc242593dc877b3496b --- /dev/null +++ b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/test/sharness/.gitignore @@ -0,0 +1,3 @@ +lib/sharness/ +test-results/ +trash directory.*.sh/ diff --git a/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/test/sharness/Makefile b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/test/sharness/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..ad806a07d0082ed8bce5ed47225913acf8c80d1e --- /dev/null +++ b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/test/sharness/Makefile @@ -0,0 +1,37 @@ +# Run tests +# +# Copyright (c) 2014 Christian Couder +# MIT Licensed; see the LICENSE file in this repository. +# + +# NOTE: run with TEST_VERBOSE=1 for verbose sharness tests. + +T = $(sort $(wildcard t[0-9][0-9][0-9][0-9]-*.sh)) +BINS = bin/multihash +SHARNESS = lib/sharness/sharness.sh + +all: clean deps $(T) aggregate + +clean: + @echo "*** $@ ***" + -rm -rf test-results + +$(T): + @echo "*** $@ ***" + ./$@ + +aggregate: + @echo "*** $@ ***" + lib/test-aggregate-results.sh + +deps: $(SHARNESS) $(BINS) + +$(SHARNESS): + @echo "*** installing $@ ***" + lib/install-sharness.sh + +bin/%: + @echo "*** installing $@ ***" + cd .. && make $@ + +.PHONY: all clean $(T) aggregate diff --git a/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/test/sharness/bin b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/test/sharness/bin new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/test/sharness/lib/install-sharness.sh b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/test/sharness/lib/install-sharness.sh new file mode 100644 index 0000000000000000000000000000000000000000..d573c4069d95447936267ad1697b160e8578a6a0 --- /dev/null +++ b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/test/sharness/lib/install-sharness.sh @@ -0,0 +1,26 @@ +#!/bin/sh +# install sharness.sh +# +# Copyright (c) 2014 Juan Batiz-Benet +# MIT Licensed; see the LICENSE file in this repository. +# + +# settings +version=50229a79ba22b2f13ccd82451d86570fecbd194c +urlprefix=https://github.com/mlafeldt/sharness.git +clonedir=lib +sharnessdir=sharness + +die() { + echo >&2 "$@" + exit 1 +} + +mkdir -p "$clonedir" || die "Could not create '$clonedir' directory" +cd "$clonedir" || die "Could not cd into '$clonedir' directory" + +git clone "$urlprefix" || die "Could not clone '$urlprefix'" +cd "$sharnessdir" || die "Could not cd into '$sharnessdir' directory" +git checkout "$version" || die "Could not checkout '$version'" + +exit 0 diff --git a/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/test/sharness/lib/test-aggregate-results.sh b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/test/sharness/lib/test-aggregate-results.sh new file mode 100644 index 0000000000000000000000000000000000000000..c2ff76ca1d901c8accbec4db3f501f391f35bf8f --- /dev/null +++ b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/test/sharness/lib/test-aggregate-results.sh @@ -0,0 +1,17 @@ +#!/bin/sh +# +# Script to aggregate results using Sharness +# +# Copyright (c) 2014 Christian Couder +# MIT Licensed; see the LICENSE file in this repository. +# + +SHARNESS_AGGREGATE="lib/sharness/aggregate-results.sh" + +test -f "$SHARNESS_AGGREGATE" || { + echo >&2 "Cannot find: $SHARNESS_AGGREGATE" + echo >&2 "Please check Sharness installation." + exit 1 +} + +ls test-results/t*-*.sh.*.counts | "$SHARNESS_AGGREGATE" diff --git a/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/test/sharness/lib/test-lib.sh b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/test/sharness/lib/test-lib.sh new file mode 100644 index 0000000000000000000000000000000000000000..988164ab273a681f4f017910b8c299f4ba2e78dc --- /dev/null +++ b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/test/sharness/lib/test-lib.sh @@ -0,0 +1,43 @@ +# Test framework for go-ipfs +# +# Copyright (c) 2014 Christian Couder +# MIT Licensed; see the LICENSE file in this repository. +# +# We are using sharness (https://github.com/mlafeldt/sharness) +# which was extracted from the Git test framework. + +# Use the multihash tool to test against + +# Add current directory to path, for multihash tool. +PATH=$(pwd)/bin:${PATH} + +# Set sharness verbosity. we set the env var directly as +# it's too late to pass in --verbose, and --verbose is harder +# to pass through in some cases. +test "$TEST_VERBOSE" = 1 && verbose=t + +# assert the `multihash` we're using is the right one. +if test `which multihash` != $(pwd)/bin/multihash; then + echo >&2 "Cannot find the tests' local multihash tool." + echo >&2 "Please check test and multihash tool installation." + exit 1 +fi + +SHARNESS_LIB="lib/sharness/sharness.sh" + +. "$SHARNESS_LIB" || { + echo >&2 "Cannot source: $SHARNESS_LIB" + echo >&2 "Please check Sharness installation." + exit 1 +} + +# Please put go-multihash specific shell functions below + +for hashbin in sha1sum shasum; do + if type "$hashbin"; then + export SHASUMBIN="$hashbin" && + test_set_prereq SHASUM && + break + fi +done + diff --git a/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/test/sharness/t0010-basics.sh b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/test/sharness/t0010-basics.sh new file mode 100644 index 0000000000000000000000000000000000000000..1ff86ff5d7889d8e2a85a18c58accafc84d43835 --- /dev/null +++ b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/test/sharness/t0010-basics.sh @@ -0,0 +1,25 @@ +#!/bin/sh +# +# Copyright (c) 2015 Christian Couder +# MIT Licensed; see the LICENSE file in this repository. +# + +test_description="Basic tests" + +. lib/test-lib.sh + +test_expect_success "current dir is writable" ' + echo "It works!" >test.txt +' + +test_expect_success "multihash is available" ' + type multihash +' + +test_expect_success "multihash help output looks good" ' + test_must_fail multihash -h 2>help.txt && + cat help.txt | egrep -i "^usage:" >/dev/null && + cat help.txt | egrep -i "multihash .*options.*file" >/dev/null +' + +test_done diff --git a/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/test/sharness/t0020-sha1.sh b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/test/sharness/t0020-sha1.sh new file mode 100644 index 0000000000000000000000000000000000000000..a5be58ba5f3f545aa8241bb24491571d64871b6d --- /dev/null +++ b/vendor/QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/test/sharness/t0020-sha1.sh @@ -0,0 +1,31 @@ +#!/bin/sh +# +# Copyright (c) 2015 Christian Couder +# MIT Licensed; see the LICENSE file in this repository. +# + +test_description="sha1 tests" + +. lib/test-lib.sh + +test_expect_success "setup sha1 tests" ' + echo "Hash me!" >hash_me.txt && + SHA1=bc6f2c3cd945bc754789e50b2f68deee2f421810 && + echo "1114$SHA1" >actual +' + +test_expect_success "'multihash -a=sha1 -e=hex' works" ' + multihash -a=sha1 -e=hex hash_me.txt >expected +' + +test_expect_success "'multihash -a=sha1 -e=hex' output looks good" ' + test_cmp expected actual +' + +test_expect_success SHASUM "check hash using shasum" ' + echo "$SHA1 hash_me.txt" >actual && + $SHASUMBIN hash_me.txt >expected && + test_cmp expected actual +' + +test_done diff --git a/vendor/util/eventlog/loggables/loggables.go b/vendor/util/eventlog/loggables/loggables.go index 7b405349b77c56e2e7d99eed8a3dd5949ef8119a..63b84f97c6d1fab8d24aa5c2a147d9b35a22a324 100644 --- a/vendor/util/eventlog/loggables/loggables.go +++ b/vendor/util/eventlog/loggables/loggables.go @@ -9,7 +9,7 @@ package loggables import ( "net" - ma "github.com/jbenet/go-multiaddr" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" logging "QmWRypnfEwrgH4k93KEHN5hng7VjKYkWmzDYRuTZeh2Mgh/go-log" diff --git a/vendor/util/testutil/gen.go b/vendor/util/testutil/gen.go index 13177eddca4d560d97b05142c25cc02138d6d495..87cde6108036460899a01df681a0516588c9044b 100644 --- a/vendor/util/testutil/gen.go +++ b/vendor/util/testutil/gen.go @@ -12,7 +12,7 @@ import ( peer "github.com/ipfs/go-libp2p/p2p/peer" u "util" - ma "github.com/jbenet/go-multiaddr" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" ) // ZeroLocalTCPAddress is the "zero" tcp local multiaddr. This means: diff --git a/vendor/util/testutil/identity.go b/vendor/util/testutil/identity.go index 04a8ead835afc1d4c4eb2a3dc480b32a87940577..a92126a9a80f35554f42fad8f6d1e8e0b0414040 100644 --- a/vendor/util/testutil/identity.go +++ b/vendor/util/testutil/identity.go @@ -3,9 +3,9 @@ package testutil import ( "testing" + ma "QmaA6aDzeHjZiuqBtgYRz8ZXb1qMCoyMHgyDjBEYQniUKF/go-multiaddr" ci "github.com/ipfs/go-libp2p/p2p/crypto" peer "github.com/ipfs/go-libp2p/p2p/peer" - ma "github.com/jbenet/go-multiaddr" ) type Identity interface { diff --git a/vendor/util/util.go b/vendor/util/util.go index 1ce3a19b4e168f4e86e90b38ad10b3509726e76d..d5a4de66eb22f4fa8f93f09e5de40acb0b801dc0 100644 --- a/vendor/util/util.go +++ b/vendor/util/util.go @@ -12,8 +12,8 @@ import ( "strings" "time" - b58 "github.com/jbenet/go-base58" - mh "github.com/jbenet/go-multihash" + b58 "QmNsoHoCVhgXcv1Yg45jtkMgimxorTAN36fV9AQMFXHHAQ/go-base58" + mh "QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash" ) // Debug is a global flag for debugging.