1
1
'use strict'
2
2
3
- const debug = require ( 'debug' )
4
- const log = debug ( 'libp2p:tcp' )
5
- const tcp = require ( 'net' )
6
- const multiaddr = require ( 'multiaddr' )
7
- const Address6 = require ( 'ip-address' ) . Address6
3
+ const net = require ( 'net' )
4
+ const toPull = require ( 'stream-to-pull-stream' )
8
5
const mafmt = require ( 'mafmt' )
9
- // const parallel = require('run-parallel')
10
6
const contains = require ( 'lodash.contains' )
11
- const os = require ( 'os ' )
7
+ const isFunction = require ( 'lodash.isfunction ' )
12
8
const Connection = require ( 'interface-connection' ) . Connection
9
+ const debug = require ( 'debug' )
10
+ const log = debug ( 'libp2p:tcp' )
13
11
14
- exports = module . exports = TCP
15
-
16
- const IPFS_CODE = 421
17
- const CLOSE_TIMEOUT = 2000
18
-
19
- function TCP ( ) {
20
- if ( ! ( this instanceof TCP ) ) {
21
- return new TCP ( )
22
- }
12
+ const createListener = require ( './listener' )
23
13
24
- this . dial = function ( ma , options , callback ) {
25
- if ( typeof options === 'function' ) {
26
- callback = options
14
+ module . exports = class TCP {
15
+ dial ( ma , options , cb ) {
16
+ if ( isFunction ( options ) ) {
17
+ cb = options
27
18
options = { }
28
19
}
29
20
30
- if ( ! callback ) {
31
- callback = function noop ( ) { }
21
+ if ( ! cb ) {
22
+ cb = ( ) => { }
32
23
}
33
24
34
- const socket = tcp . connect ( ma . toOptions ( ) )
35
- const conn = new Connection ( socket )
36
-
37
- socket . on ( 'timeout' , ( ) => {
38
- conn . emit ( 'timeout' )
39
- } )
40
-
41
- socket . once ( 'error' , ( err ) => {
42
- callback ( err )
43
- } )
44
-
45
- socket . on ( 'connect' , ( ) => {
46
- callback ( null , conn )
47
- conn . emit ( 'connect' )
48
- } )
25
+ const cOpts = ma . toOptions ( )
26
+ log ( 'Connecting to %s %s' , cOpts . port , cOpts . host )
27
+ const socket = toPull . duplex ( net . connect ( cOpts , cb ) )
49
28
50
- conn . getObservedAddrs = ( cb ) => {
29
+ socket . getObservedAddrs = ( cb ) => {
51
30
return cb ( null , [ ma ] )
52
31
}
53
32
54
- return conn
33
+ return new Connection ( socket )
55
34
}
56
35
57
- this . createListener = ( options , handler ) => {
58
- if ( typeof options === 'function' ) {
36
+ createListener ( options , handler ) {
37
+ if ( isFunction ( options ) ) {
59
38
handler = options
60
39
options = { }
61
40
}
62
41
63
- const listener = tcp . createServer ( ( socket ) => {
64
- const conn = new Connection ( socket )
65
-
66
- conn . getObservedAddrs = ( cb ) => {
67
- return cb ( null , [ getMultiaddr ( socket ) ] )
68
- }
69
- handler ( conn )
70
- } )
71
-
72
- let ipfsId
73
- let listeningMultiaddr
74
-
75
- listener . _listen = listener . listen
76
- listener . listen = ( ma , callback ) => {
77
- listeningMultiaddr = ma
78
- if ( contains ( ma . protoNames ( ) , 'ipfs' ) ) {
79
- ipfsId = ma . stringTuples ( ) . filter ( ( tuple ) => {
80
- if ( tuple [ 0 ] === IPFS_CODE ) {
81
- return true
82
- }
83
- } ) [ 0 ] [ 1 ]
84
- listeningMultiaddr = ma . decapsulate ( 'ipfs' )
85
- }
86
-
87
- listener . _listen ( listeningMultiaddr . toOptions ( ) , callback )
88
- }
89
-
90
- listener . _close = listener . close
91
- listener . close = ( options , callback ) => {
92
- if ( typeof options === 'function' ) {
93
- callback = options
94
- options = { }
95
- }
96
- if ( ! callback ) { callback = function noop ( ) { } }
97
- if ( ! options ) { options = { } }
98
-
99
- let closed = false
100
- listener . _close ( callback )
101
- listener . once ( 'close' , ( ) => {
102
- closed = true
103
- } )
104
- setTimeout ( ( ) => {
105
- if ( closed ) {
106
- return
107
- }
108
- log ( 'unable to close graciously, destroying conns' )
109
- Object . keys ( listener . __connections ) . forEach ( ( key ) => {
110
- log ( 'destroying %s' , key )
111
- listener . __connections [ key ] . destroy ( )
112
- } )
113
- } , options . timeout || CLOSE_TIMEOUT )
114
- }
115
-
116
- // Keep track of open connections to destroy in case of timeout
117
- listener . __connections = { }
118
- listener . on ( 'connection' , ( socket ) => {
119
- const key = `${ socket . remoteAddress } :${ socket . remotePort } `
120
- listener . __connections [ key ] = socket
121
-
122
- socket . on ( 'close' , ( ) => {
123
- delete listener . __connections [ key ]
124
- } )
125
- } )
126
-
127
- listener . getAddrs = ( callback ) => {
128
- const multiaddrs = [ ]
129
- const address = listener . address ( )
130
-
131
- // Because TCP will only return the IPv6 version
132
- // we need to capture from the passed multiaddr
133
- if ( listeningMultiaddr . toString ( ) . indexOf ( 'ip4' ) !== - 1 ) {
134
- let m = listeningMultiaddr . decapsulate ( 'tcp' )
135
- m = m . encapsulate ( '/tcp/' + address . port )
136
- if ( ipfsId ) {
137
- m = m . encapsulate ( '/ipfs/' + ipfsId )
138
- }
139
-
140
- if ( m . toString ( ) . indexOf ( '0.0.0.0' ) !== - 1 ) {
141
- const netInterfaces = os . networkInterfaces ( )
142
- Object . keys ( netInterfaces ) . forEach ( ( niKey ) => {
143
- netInterfaces [ niKey ] . forEach ( ( ni ) => {
144
- if ( ni . family === 'IPv4' ) {
145
- multiaddrs . push ( multiaddr ( m . toString ( ) . replace ( '0.0.0.0' , ni . address ) ) )
146
- }
147
- } )
148
- } )
149
- } else {
150
- multiaddrs . push ( m )
151
- }
152
- }
153
-
154
- if ( address . family === 'IPv6' ) {
155
- let ma = multiaddr ( '/ip6/' + address . address + '/tcp/' + address . port )
156
- if ( ipfsId ) {
157
- ma = ma . encapsulate ( '/ipfs/' + ipfsId )
158
- }
159
-
160
- multiaddrs . push ( ma )
161
- }
162
-
163
- callback ( null , multiaddrs )
164
- }
165
-
166
- return listener
167
- /*
168
- listener.listen(m.toOptions(), () => {
169
- // Node.js likes to convert addr to IPv6 (when 0.0.0.0 for e.g)
170
- const address = listener.address()
171
- if (m.toString().indexOf('ip4')) {
172
- m = m.decapsulate('tcp')
173
- m = m.encapsulate('/tcp/' + address.port)
174
- if (ipfsHashId) {
175
- m = m.encapsulate('/ipfs/' + ipfsHashId)
176
- }
177
- freshMultiaddrs.push(m)
178
- }
179
-
180
- if (address.family === 'IPv6') {
181
- let mh = multiaddr('/ip6/' + address.address + '/tcp/' + address.port)
182
- if (ipfsHashId) {
183
- mh = mh.encapsulate('/ipfs/' + ipfsHashId)
184
- }
185
-
186
- freshMultiaddrs.push(mh)
187
- }
188
-
189
- cb()
190
- })
191
- listeners.push(listener)
192
- */
42
+ return createListener ( handler )
193
43
}
194
44
195
- this . filter = ( multiaddrs ) => {
45
+ filter ( multiaddrs ) {
196
46
if ( ! Array . isArray ( multiaddrs ) ) {
197
47
multiaddrs = [ multiaddrs ]
198
48
}
@@ -204,21 +54,3 @@ function TCP () {
204
54
} )
205
55
}
206
56
}
207
-
208
- function getMultiaddr ( socket ) {
209
- var mh
210
-
211
- if ( socket . remoteFamily === 'IPv6' ) {
212
- var addr = new Address6 ( socket . remoteAddress )
213
- if ( addr . v4 ) {
214
- var ip4 = addr . to4 ( ) . correctForm ( )
215
- mh = multiaddr ( '/ip4/' + ip4 + '/tcp/' + socket . remotePort )
216
- } else {
217
- mh = multiaddr ( '/ip6/' + socket . remoteAddress + '/tcp/' + socket . remotePort )
218
- }
219
- } else {
220
- mh = multiaddr ( '/ip4/' + socket . remoteAddress + '/tcp/' + socket . remotePort )
221
- }
222
-
223
- return mh
224
- }
0 commit comments