@@ -104,7 +104,7 @@ class RLPxConnectionHandler(
104
104
105
105
case Failure (ex) =>
106
106
log.debug(
107
- s " [Stopping Connection] Init AuthHandshaker message handling failed for peer {} due to {} " ,
107
+ " [Stopping Connection] Init AuthHandshaker message handling failed for peer {} due to {}" ,
108
108
peerId,
109
109
ex.getMessage
110
110
)
@@ -132,7 +132,7 @@ class RLPxConnectionHandler(
132
132
133
133
case Failure (ex) =>
134
134
log.debug(
135
- s " [Stopping Connection] Response AuthHandshaker message handling failed for peer {} due to {} " ,
135
+ " [Stopping Connection] Response AuthHandshaker message handling failed for peer {} due to {}" ,
136
136
peerId,
137
137
ex.getMessage
138
138
)
@@ -154,24 +154,25 @@ class RLPxConnectionHandler(
154
154
}
155
155
156
156
def handleTimeout : Receive = { case AuthHandshakeTimeout =>
157
- log.debug(s " [Stopping Connection] Auth handshake timeout for peer {} " , peerId)
157
+ log.debug(" [Stopping Connection] Auth handshake timeout for peer {}" , peerId)
158
158
context.parent ! ConnectionFailed
159
159
context stop self
160
160
}
161
161
162
162
def processHandshakeResult (result : AuthHandshakeResult , remainingData : ByteString ): Unit =
163
163
result match {
164
164
case AuthHandshakeSuccess (secrets, remotePubKey) =>
165
- log.debug(s " Auth handshake succeeded for peer {} " , peerId)
165
+ log.debug(" Auth handshake succeeded for peer {}" , peerId)
166
166
context.parent ! ConnectionEstablished (remotePubKey)
167
- if (remainingData.nonEmpty)
168
- context.self ! Received (remainingData)
169
167
// following the specification at https://github.com/ethereum/devp2p/blob/master/rlpx.md#initial-handshake
170
168
// point 6 indicates that the next messages needs to be initial 'Hello'
171
- context become awaitInitialHello(extractor(secrets))
169
+ // Unfortunately it is hard to figure out the proper order for messages to be handled in.
170
+ // FrameCodec assumes that bytes will arrive in the expected order
171
+ // To alleviate potential lapses in order each chunk of data needs to be passed to FrameCodec immediately
172
+ extractHello(extractor(secrets), remainingData)
172
173
173
174
case AuthHandshakeError =>
174
- log.debug(s " [Stopping Connection] Auth handshake failed for peer {} " , peerId)
175
+ log.debug(" [Stopping Connection] Auth handshake failed for peer {}" , peerId)
175
176
context.parent ! ConnectionFailed
176
177
context stop self
177
178
}
@@ -181,45 +182,37 @@ class RLPxConnectionHandler(
181
182
cancellableAckTimeout : Option [CancellableAckTimeout ] = None ,
182
183
seqNumber : Int = 0
183
184
): Receive =
184
- handleWriteFailed orElse handleConnectionClosed orElse handleSendHello(
185
- extractor,
186
- cancellableAckTimeout,
187
- seqNumber
188
- ) orElse handleReceiveHello(extractor, cancellableAckTimeout, seqNumber)
189
-
190
- private def handleSendHello (
191
- extractor : HelloCodec ,
192
- cancellableAckTimeout : Option [CancellableAckTimeout ] = None ,
193
- seqNumber : Int = 0
194
- ): Receive = {
195
- // TODO when cancellableAckTimeout is Some
196
- case SendMessage (h : HelloEnc ) =>
197
- val out = extractor.writeHello(h)
198
- connection ! Write (out, Ack )
199
- val timeout =
200
- system.scheduler.scheduleOnce(rlpxConfiguration.waitForTcpAckTimeout, self, AckTimeout (seqNumber))
201
- context become awaitInitialHello(
202
- extractor,
203
- Some (CancellableAckTimeout (seqNumber, timeout)),
204
- increaseSeqNumber(seqNumber)
205
- )
206
- case Ack if cancellableAckTimeout.nonEmpty =>
207
- // Cancel pending message timeout
208
- cancellableAckTimeout.foreach(_.cancellable.cancel())
209
- context become awaitInitialHello(extractor, None , seqNumber)
210
-
211
- case AckTimeout (ackSeqNumber) if cancellableAckTimeout.exists(_.seqNumber == ackSeqNumber) =>
212
- cancellableAckTimeout.foreach(_.cancellable.cancel())
213
- log.error(s " [Stopping Connection] Sending 'Hello' to {} failed " , peerId)
214
- context stop self
185
+ handleWriteFailed orElse handleConnectionClosed orElse {
186
+ // TODO when cancellableAckTimeout is Some
187
+ case SendMessage (h : HelloEnc ) =>
188
+ val out = extractor.writeHello(h)
189
+ connection ! Write (out, Ack )
190
+ val timeout =
191
+ system.scheduler.scheduleOnce(rlpxConfiguration.waitForTcpAckTimeout, self, AckTimeout (seqNumber))
192
+ context become awaitInitialHello(
193
+ extractor,
194
+ Some (CancellableAckTimeout (seqNumber, timeout)),
195
+ increaseSeqNumber(seqNumber)
196
+ )
197
+ case Ack if cancellableAckTimeout.nonEmpty =>
198
+ // Cancel pending message timeout
199
+ cancellableAckTimeout.foreach(_.cancellable.cancel())
200
+ context become awaitInitialHello(extractor, None , seqNumber)
215
201
216
- }
202
+ case AckTimeout (ackSeqNumber) if cancellableAckTimeout.exists(_.seqNumber == ackSeqNumber) =>
203
+ cancellableAckTimeout.foreach(_.cancellable.cancel())
204
+ log.error(" [Stopping Connection] Sending 'Hello' to {} failed" , peerId)
205
+ context stop self
206
+ case Received (data) =>
207
+ extractHello(extractor, data, cancellableAckTimeout, seqNumber)
208
+ }
217
209
218
- private def handleReceiveHello (
210
+ private def extractHello (
219
211
extractor : HelloCodec ,
212
+ data : ByteString ,
220
213
cancellableAckTimeout : Option [CancellableAckTimeout ] = None ,
221
214
seqNumber : Int = 0
222
- ): Receive = { case Received (data) =>
215
+ ): Unit = {
223
216
extractor.readHello(data) match {
224
217
case Some ((hello, restFrames)) =>
225
218
val messageCodecOpt = for {
@@ -236,12 +229,12 @@ class RLPxConnectionHandler(
236
229
seqNumber = seqNumber
237
230
)
238
231
case None =>
239
- log.debug(s " [Stopping Connection] Unable to negotiate protocol with {} " , peerId)
232
+ log.debug(" [Stopping Connection] Unable to negotiate protocol with {}" , peerId)
240
233
context.parent ! ConnectionFailed
241
234
context stop self
242
235
}
243
236
case None =>
244
- log.debug(s " [Stopping Connection] Did not find 'Hello' in message from {} " , peerId)
237
+ log.debug(" [Stopping Connection] Did not find 'Hello' in message from {}" , peerId)
245
238
context become awaitInitialHello(extractor, cancellableAckTimeout, seqNumber)
246
239
}
247
240
}
@@ -262,7 +255,7 @@ class RLPxConnectionHandler(
262
255
context.parent ! MessageReceived (message)
263
256
264
257
case Failure (ex) =>
265
- log.info(s " Cannot decode message from {}, because of {} " , peerId, ex.getMessage)
258
+ log.info(" Cannot decode message from {}, because of {}" , peerId, ex.getMessage)
266
259
// break connection in case of failed decoding, to avoid attack which would send us garbage
267
260
context stop self
268
261
}
@@ -310,7 +303,7 @@ class RLPxConnectionHandler(
310
303
311
304
case AckTimeout (ackSeqNumber) if cancellableAckTimeout.exists(_.seqNumber == ackSeqNumber) =>
312
305
cancellableAckTimeout.foreach(_.cancellable.cancel())
313
- log.debug(s " [Stopping Connection] Write to {} failed " , peerId)
306
+ log.debug(" [Stopping Connection] Write to {} failed" , peerId)
314
307
context stop self
315
308
}
316
309
}
@@ -332,7 +325,7 @@ class RLPxConnectionHandler(
332
325
): Unit = {
333
326
val out = messageCodec.encodeMessage(messageToSend)
334
327
connection ! Write (out, Ack )
335
- log.debug(s " Sent message: {} to {} " , messageToSend.underlyingMsg.toShortString, peerId)
328
+ log.debug(" Sent message: {} to {}" , messageToSend.underlyingMsg.toShortString, peerId)
336
329
337
330
val timeout = system.scheduler.scheduleOnce(rlpxConfiguration.waitForTcpAckTimeout, self, AckTimeout (seqNumber))
338
331
context become handshaked(
@@ -356,7 +349,7 @@ class RLPxConnectionHandler(
356
349
357
350
def handleWriteFailed : Receive = { case CommandFailed (cmd : Write ) =>
358
351
log.debug(
359
- s " [Stopping Connection] Write to peer {} failed, trying to send {} " ,
352
+ " [Stopping Connection] Write to peer {} failed, trying to send {}" ,
360
353
peerId,
361
354
Hex .toHexString(cmd.data.toArray[Byte ])
362
355
)
@@ -365,10 +358,10 @@ class RLPxConnectionHandler(
365
358
366
359
def handleConnectionClosed : Receive = { case msg : ConnectionClosed =>
367
360
if (msg.isPeerClosed) {
368
- log.debug(s " [Stopping Connection] Connection with {} closed by peer " , peerId)
361
+ log.debug(" [Stopping Connection] Connection with {} closed by peer" , peerId)
369
362
}
370
363
if (msg.isErrorClosed) {
371
- log.debug(s " [Stopping Connection] Connection with {} closed because of error {} " , peerId, msg.getErrorCause)
364
+ log.debug(" [Stopping Connection] Connection with {} closed because of error {}" , peerId, msg.getErrorCause)
372
365
}
373
366
374
367
context stop self
0 commit comments