@cryptotaxi247 / kubo / commits / f4ba724db

implement utp transport

License: MIT Signed-off-by: Jeromy <jeromyj@gmail.com>

Jeromy committed Dec 8, 2015 at 15:37 UTC f4ba724dbe1ad3c64884b7433eb80e99e5a9f777
6 files changed +170 -19
p2p/net/swarm/addr/addr.go
+2 -2
@@ -18,8 +18,8 @@ var log = logging.Logger("p2p/net/swarm/addr")
18 var SupportedTransportStrings = []string{
19 "/ip4/tcp",
20 "/ip6/tcp",
21 - // "/ip4/udp/utp", disabled because the lib is broken
22 - // "/ip6/udp/utp", disabled because the lib is broken
21 + "/ip4/udp/utp",
22 + "/ip6/udp/utp",
23 // "/ip4/udp/udt", disabled because the lib doesnt work on arm
24 // "/ip6/udp/udt", disabled because the lib doesnt work on arm
25 }
p2p/net/swarm/addr/addr_test.go
+1 -7
@@ -20,7 +20,6 @@ func TestFilterAddrs(t *testing.T) {
20 bad := []ma.Multiaddr{
21 newMultiaddr(t, "/ip4/1.2.3.4/udp/1234"), // unreliable
22 newMultiaddr(t, "/ip4/1.2.3.4/udp/1234/sctp/1234"), // not in manet
23 - newMultiaddr(t, "/ip4/1.2.3.4/udp/1234/utp"), // utp is broken
23 newMultiaddr(t, "/ip4/1.2.3.4/udp/1234/udt"), // udt is broken on arm
24 newMultiaddr(t, "/ip6/fe80::1/tcp/1234"), // link local
25 newMultiaddr(t, "/ip6/fe80::100/tcp/1234"), // link local
@@ -29,6 +28,7 @@ func TestFilterAddrs(t *testing.T) {
28 good := []ma.Multiaddr{
29 newMultiaddr(t, "/ip4/127.0.0.1/tcp/1234"),
30 newMultiaddr(t, "/ip6/::1/tcp/1234"),
31 + newMultiaddr(t, "/ip4/1.2.3.4/udp/1234/utp"),
32 }
33
34 goodAndBad := append(good, bad...)
@@ -39,18 +39,12 @@ func TestFilterAddrs(t *testing.T) {
39 if AddrUsable(a, false) {
40 t.Errorf("addr %s should be unusable", a)
41 }
42 - if AddrUsable(a, true) {
43 - t.Errorf("addr %s should be unusable", a)
44 - }
42 }
43
44 for _, a := range good {
45 if !AddrUsable(a, false) {
46 t.Errorf("addr %s should be usable", a)
47 }
51 - if !AddrUsable(a, true) {
52 - t.Errorf("addr %s should be usable", a)
53 - }
48 }
49
50 subtestAddrsEqual(t, FilterUsableAddrs(bad), []ma.Multiaddr{})
p2p/net/swarm/swarm.go
+10 -7
@@ -91,13 +91,16 @@ func NewSwarm(ctx context.Context, listenAddrs []ma.Multiaddr,
91 }
92
93 s := &Swarm{
94 - swarm: ps.NewSwarm(PSTransport),
95 - local: local,
96 - peers: peers,
97 - ctx: ctx,
98 - dialT: DialTimeout,
99 - notifs: make(map[inet.Notifiee]ps.Notifiee),
100 - transports: []transport.Transport{transport.NewTCPTransport()},
94 + swarm: ps.NewSwarm(PSTransport),
95 + local: local,
96 + peers: peers,
97 + ctx: ctx,
98 + dialT: DialTimeout,
99 + notifs: make(map[inet.Notifiee]ps.Notifiee),
100 + transports: []transport.Transport{
101 + transport.NewTCPTransport(),
102 + transport.NewUtpTransport(),
103 + },
104 bwc: bwc,
105 fdRateLimit: make(chan struct{}, concurrentFdDials),
106 Filters: filter.NewFilters(),
p2p/net/swarm/swarm_addr_test.go
+3 -3
@@ -25,7 +25,6 @@ func TestFilterAddrs(t *testing.T) {
25 bad := []ma.Multiaddr{
26 m("/ip4/1.2.3.4/udp/1234"), // unreliable
27 m("/ip4/1.2.3.4/udp/1234/sctp/1234"), // not in manet
28 - m("/ip4/1.2.3.4/udp/1234/utp"), // utp is broken
28 m("/ip4/1.2.3.4/udp/1234/udt"), // udt is broken on arm
29 m("/ip6/fe80::1/tcp/0"), // link local
30 m("/ip6/fe80::100/tcp/1234"), // link local
@@ -34,6 +33,7 @@ func TestFilterAddrs(t *testing.T) {
33 good := []ma.Multiaddr{
34 m("/ip4/127.0.0.1/tcp/0"),
35 m("/ip6/::1/tcp/0"),
36 + m("/ip4/1.2.3.4/udp/1234/utp"),
37 }
38
39 goodAndBad := append(good, bad...)
@@ -41,13 +41,13 @@ func TestFilterAddrs(t *testing.T) {
41 // test filters
42
43 for _, a := range bad {
44 - if addrutil.AddrUsable(a, true) {
44 + if addrutil.AddrUsable(a, false) {
45 t.Errorf("addr %s should be unusable", a)
46 }
47 }
48
49 for _, a := range good {
50 - if !addrutil.AddrUsable(a, true) {
50 + if !addrutil.AddrUsable(a, false) {
51 t.Errorf("addr %s should be usable", a)
52 }
53 }
p2p/net/transport/utp.go new
+148
@@ -0,0 +1,148 @@
1 +package transport
2 +
3 +import (
4 + "net"
5 + "sync"
6 +
7 + utp "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/anacrolix/utp"
8 + ma "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
9 + manet "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net"
10 + mautp "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net/utp"
11 +)
12 +
13 +type UtpTransport struct {
14 + sockLock sync.Mutex
15 + sockets map[string]*UtpSocket
16 +}
17 +
18 +func NewUtpTransport() *UtpTransport {
19 + return &UtpTransport{
20 + sockets: make(map[string]*UtpSocket),
21 + }
22 +}
23 +
24 +func (d *UtpTransport) Matches(a ma.Multiaddr) bool {
25 + p := a.Protocols()
26 + return len(p) == 3 && p[2].Name == "utp"
27 +}
28 +
29 +type UtpSocket struct {
30 + s *utp.Socket
31 + laddr ma.Multiaddr
32 + transport Transport
33 +}
34 +
35 +func (t *UtpTransport) Listen(laddr ma.Multiaddr) (Listener, error) {
36 + t.sockLock.Lock()
37 + defer t.sockLock.Unlock()
38 + s, ok := t.sockets[laddr.String()]
39 + if ok {
40 + return s, nil
41 + }
42 +
43 + ns, err := t.newConn(laddr)
44 + if err != nil {
45 + return nil, err
46 + }
47 +
48 + t.sockets[laddr.String()] = ns
49 + return ns, nil
50 +}
51 +
52 +func (t *UtpTransport) Dialer(laddr ma.Multiaddr, opts ...DialOpt) (Dialer, error) {
53 + t.sockLock.Lock()
54 + defer t.sockLock.Unlock()
55 + s, ok := t.sockets[laddr.String()]
56 + if ok {
57 + return s, nil
58 + }
59 +
60 + ns, err := t.newConn(laddr, opts...)
61 + if err != nil {
62 + return nil, err
63 + }
64 +
65 + t.sockets[laddr.String()] = ns
66 + return ns, nil
67 +}
68 +
69 +func (t *UtpTransport) newConn(addr ma.Multiaddr, opts ...DialOpt) (*UtpSocket, error) {
70 + network, netaddr, err := manet.DialArgs(addr)
71 + if err != nil {
72 + return nil, err
73 + }
74 +
75 + s, err := utp.NewSocket("udp"+network[3:], netaddr)
76 + if err != nil {
77 + return nil, err
78 + }
79 +
80 + laddr, err := manet.FromNetAddr(mautp.MakeAddr(s.LocalAddr()))
81 + if err != nil {
82 + return nil, err
83 + }
84 +
85 + return &UtpSocket{
86 + s: s,
87 + laddr: laddr,
88 + transport: t,
89 + }, nil
90 +}
91 +
92 +func (s *UtpSocket) Dial(raddr ma.Multiaddr) (Conn, error) {
93 + _, addr, err := manet.DialArgs(raddr)
94 + if err != nil {
95 + return nil, err
96 + }
97 +
98 + con, err := s.s.Dial(addr)
99 + if err != nil {
100 + return nil, err
101 + }
102 +
103 + mnc, err := manet.WrapNetConn(&mautp.Conn{Conn: con})
104 + if err != nil {
105 + return nil, err
106 + }
107 +
108 + return &connWrap{
109 + Conn: mnc,
110 + transport: s.transport,
111 + }, nil
112 +}
113 +
114 +func (s *UtpSocket) Accept() (Conn, error) {
115 + c, err := s.s.Accept()
116 + if err != nil {
117 + return nil, err
118 + }
119 +
120 + mnc, err := manet.WrapNetConn(&mautp.Conn{Conn: c})
121 + if err != nil {
122 + return nil, err
123 + }
124 +
125 + return &connWrap{
126 + Conn: mnc,
127 + transport: s.transport,
128 + }, nil
129 +}
130 +
131 +func (s *UtpSocket) Matches(a ma.Multiaddr) bool {
132 + p := a.Protocols()
133 + return len(p) == 3 && p[2].Name == "utp"
134 +}
135 +
136 +func (t *UtpSocket) Close() error {
137 + return t.s.Close()
138 +}
139 +
140 +func (t *UtpSocket) Addr() net.Addr {
141 + return t.s.Addr()
142 +}
143 +
144 +func (t *UtpSocket) Multiaddr() ma.Multiaddr {
145 + return t.laddr
146 +}
147 +
148 +var _ Transport = (*UtpTransport)(nil)
test/sharness/t0130-multinode.sh
+6
@@ -78,4 +78,10 @@ test_expect_success "set up tcp testbed" '
78
79 run_basic_test
80
81 +test_expect_success "set up utp testbed" '
82 + iptb init -n 5 -p 0 -f --bootstrap=none --utp
83 +'
84 +
85 +run_basic_test
86 +
87 test_done