@libp2p/autonat-v2 1.0.0 → 1.0.1-a02cb0461

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/server.ts CHANGED
@@ -1,15 +1,14 @@
1
1
  import { ProtocolError } from '@libp2p/interface'
2
- import { isPrivateIp } from '@libp2p/utils/private-ip'
2
+ import { isPrivateIp, pbStream } from '@libp2p/utils'
3
3
  import { CODE_IP4, CODE_IP6, multiaddr } from '@multiformats/multiaddr'
4
- import { pbStream } from 'it-protobuf-stream'
5
4
  import { setMaxListeners } from 'main-event'
6
5
  import { MAX_INBOUND_STREAMS, MAX_MESSAGE_SIZE, MAX_OUTBOUND_STREAMS, TIMEOUT } from './constants.ts'
7
6
  import { DialBack, DialBackResponse, DialResponse, DialStatus, Message } from './pb/index.ts'
8
7
  import { randomNumber } from './utils.ts'
9
8
  import type { AutoNATv2Components, AutoNATv2ServiceInit } from './index.ts'
10
- import type { Logger, Connection, Startable, AbortOptions, IncomingStreamData, Stream } from '@libp2p/interface'
9
+ import type { Logger, Connection, Startable, AbortOptions, Stream } from '@libp2p/interface'
10
+ import type { ProtobufMessageStream } from '@libp2p/utils'
11
11
  import type { Multiaddr } from '@multiformats/multiaddr'
12
- import type { MessageStream } from 'it-protobuf-stream'
13
12
 
14
13
  export interface AutoNATv2ServerInit extends AutoNATv2ServiceInit {
15
14
  dialRequestProtocol: string
@@ -37,6 +36,8 @@ export class AutoNATv2Server implements Startable {
37
36
  this.maxInboundStreams = init.maxInboundStreams ?? MAX_INBOUND_STREAMS
38
37
  this.maxOutboundStreams = init.maxOutboundStreams ?? MAX_OUTBOUND_STREAMS
39
38
  this.maxMessageSize = init.maxMessageSize ?? MAX_MESSAGE_SIZE
39
+
40
+ this.handleDialRequestStream = this.handleDialRequestStream.bind(this)
40
41
  }
41
42
 
42
43
  async start (): Promise<void> {
@@ -45,12 +46,7 @@ export class AutoNATv2Server implements Startable {
45
46
  }
46
47
 
47
48
  // AutoNat server
48
- await this.components.registrar.handle(this.dialRequestProtocol, (data) => {
49
- void this.handleDialRequestStream(data)
50
- .catch(err => {
51
- this.log.error('error handling incoming autonat stream - %e', err)
52
- })
53
- }, {
49
+ await this.components.registrar.handle(this.dialRequestProtocol, this.handleDialRequestStream, {
54
50
  maxInboundStreams: this.maxInboundStreams,
55
51
  maxOutboundStreams: this.maxOutboundStreams
56
52
  })
@@ -67,100 +63,95 @@ export class AutoNATv2Server implements Startable {
67
63
  /**
68
64
  * Handle an incoming AutoNAT request
69
65
  */
70
- async handleDialRequestStream (data: IncomingStreamData): Promise<void> {
66
+ async handleDialRequestStream (stream: Stream, connection: Connection): Promise<void> {
71
67
  const signal = AbortSignal.timeout(this.timeout)
72
68
  setMaxListeners(Infinity, signal)
73
69
 
74
- const messages = pbStream(data.stream, {
70
+ const messages = pbStream(stream, {
75
71
  maxDataLength: this.maxMessageSize
76
72
  }).pb(Message)
77
73
 
78
- try {
79
- const connectionIp = getIpAddress(data.connection.remoteAddr)
74
+ const connectionIp = getIpAddress(connection.remoteAddr)
80
75
 
81
- if (connectionIp == null) {
82
- throw new ProtocolError(`Could not find IP address in connection address "${data.connection.remoteAddr}"`)
83
- }
76
+ if (connectionIp == null) {
77
+ throw new ProtocolError(`Could not find IP address in connection address "${connection.remoteAddr}"`)
78
+ }
84
79
 
85
- const { dialRequest } = await messages.read({
86
- signal
87
- })
80
+ const { dialRequest } = await messages.read({
81
+ signal
82
+ })
88
83
 
89
- if (dialRequest == null) {
90
- throw new ProtocolError('Did not receive DialRequest message on incoming dial request stream')
91
- }
84
+ if (dialRequest == null) {
85
+ throw new ProtocolError('Did not receive DialRequest message on incoming dial request stream')
86
+ }
92
87
 
93
- if (dialRequest.addrs.length === 0) {
94
- throw new ProtocolError('Did not receive any addresses to dial')
95
- }
88
+ if (dialRequest.addrs.length === 0) {
89
+ throw new ProtocolError('Did not receive any addresses to dial')
90
+ }
96
91
 
97
- for (let i = 0; i < dialRequest.addrs.length; i++) {
98
- try {
99
- const ma = multiaddr(dialRequest.addrs[i])
100
- const isDialable = await this.components.connectionManager.isDialable(ma, {
92
+ for (let i = 0; i < dialRequest.addrs.length; i++) {
93
+ try {
94
+ const ma = multiaddr(dialRequest.addrs[i])
95
+ const isDialable = await this.components.connectionManager.isDialable(ma, {
96
+ signal
97
+ })
98
+
99
+ if (!isDialable) {
100
+ await messages.write({
101
+ dialResponse: {
102
+ addrIdx: i,
103
+ status: DialResponse.ResponseStatus.E_DIAL_REFUSED,
104
+ dialStatus: DialStatus.UNUSED
105
+ }
106
+ }, {
101
107
  signal
102
108
  })
103
109
 
104
- if (!isDialable) {
105
- await messages.write({
106
- dialResponse: {
107
- addrIdx: i,
108
- status: DialResponse.ResponseStatus.E_DIAL_REFUSED,
109
- dialStatus: DialStatus.UNUSED
110
- }
111
- }, {
112
- signal
113
- })
114
-
115
- continue
116
- }
117
-
118
- const ip = getIpAddress(ma)
119
-
120
- if (ip == null) {
121
- throw new ProtocolError(`Could not find IP address in requested address "${ma}"`)
122
- }
110
+ continue
111
+ }
123
112
 
124
- if (isPrivateIp(ip)) {
125
- throw new ProtocolError(`Requested address had private IP "${ma}"`)
126
- }
113
+ const ip = getIpAddress(ma)
127
114
 
128
- if (ip !== connectionIp) {
129
- // amplification attack protection - request the client sends us a
130
- // random number of bytes before we'll dial the address
131
- await this.preventAmplificationAttack(messages, i, {
132
- signal
133
- })
134
- }
115
+ if (ip == null) {
116
+ throw new ProtocolError(`Could not find IP address in requested address "${ma}"`)
117
+ }
135
118
 
136
- const dialStatus = await this.dialClientBack(ma, dialRequest.nonce, {
137
- signal
138
- })
119
+ if (isPrivateIp(ip)) {
120
+ throw new ProtocolError(`Requested address had private IP "${ma}"`)
121
+ }
139
122
 
140
- await messages.write({
141
- dialResponse: {
142
- addrIdx: i,
143
- status: DialResponse.ResponseStatus.OK,
144
- dialStatus
145
- }
146
- }, {
123
+ if (ip !== connectionIp) {
124
+ // amplification attack protection - request the client sends us a
125
+ // random number of bytes before we'll dial the address
126
+ await this.preventAmplificationAttack(messages, i, {
147
127
  signal
148
128
  })
149
- } catch (err) {
150
- this.log.error('could not parse multiaddr - %e', err)
151
129
  }
152
- }
153
130
 
154
- await data.stream.close({
155
- signal
156
- })
157
- } catch (err: any) {
158
- this.log.error('error handling incoming autonat stream - %e', err)
159
- data.stream.abort(err)
131
+ const dialStatus = await this.dialClientBack(ma, dialRequest.nonce, {
132
+ signal
133
+ })
134
+
135
+ await messages.write({
136
+ dialResponse: {
137
+ addrIdx: i,
138
+ status: DialResponse.ResponseStatus.OK,
139
+ dialStatus
140
+ }
141
+ }, {
142
+ signal
143
+ })
144
+ } catch (err) {
145
+ this.log.error('error handling incoming dialback request - %e', err)
146
+ }
160
147
  }
148
+
149
+ await stream.close({
150
+ signal
151
+ })
161
152
  }
162
153
 
163
- private async preventAmplificationAttack (messages: MessageStream<Message, Stream>, index: number, options: AbortOptions): Promise<void> {
154
+ private async preventAmplificationAttack (messages: ProtobufMessageStream<Message, Stream>, index: number, options: AbortOptions): Promise<void> {
164
155
  const numBytes = randomNumber(30_000, 100_000)
165
156
 
166
157
  await messages.write({
@@ -207,7 +198,7 @@ export class AutoNATv2Server implements Startable {
207
198
  nonce
208
199
  }, DialBack, options)
209
200
 
210
- const response = await dialBackMessages.read(DialBackResponse)
201
+ const response = await dialBackMessages.read(DialBackResponse, options)
211
202
 
212
203
  if (response.status !== DialBackResponse.DialBackStatus.OK) {
213
204
  throw new ProtocolError('DialBackResponse status was not OK')
@@ -1,8 +0,0 @@
1
- {
2
- "AutoNATv2Components": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_autonat-v2.AutoNATv2Components.html",
3
- ".:AutoNATv2Components": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_autonat-v2.AutoNATv2Components.html",
4
- "AutoNATv2ServiceInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_autonat-v2.AutoNATv2ServiceInit.html",
5
- ".:AutoNATv2ServiceInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_autonat-v2.AutoNATv2ServiceInit.html",
6
- "autoNATv2": "https://libp2p.github.io/js-libp2p/functions/_libp2p_autonat-v2.autoNATv2.html",
7
- ".:autoNATv2": "https://libp2p.github.io/js-libp2p/functions/_libp2p_autonat-v2.autoNATv2.html"
8
- }