use of org.ethereum.net.p2p.HelloMessage in project rskj by rsksmart.
the class HelloMessageTest method test1.
// Parsing from raw bytes
@Test
public void test1() {
String helloMessageRaw = "f87902a5457468657265756d282b2b292f76302e372e392f52656c656173652f4c696e75782f672b2bccc58365746827c583736868018203e0b8401fbf1e41f08078918c9f7b6734594ee56d7f538614f602c71194db0a1af5a77f9b86eb14669fe7a8a46a2dd1b7d070b94e463f4ecd5b337c8b4d31bbf8dd5646";
byte[] payload = Hex.decode(helloMessageRaw);
HelloMessage helloMessage = new HelloMessage(payload);
logger.info(helloMessage.toString());
assertEquals(P2pMessageCodes.HELLO, helloMessage.getCommand());
assertEquals(2, helloMessage.getP2PVersion());
assertEquals("Ethereum(++)/v0.7.9/Release/Linux/g++", helloMessage.getClientId());
assertEquals(2, helloMessage.getCapabilities().size());
assertEquals(992, helloMessage.getListenPort());
assertEquals("1fbf1e41f08078918c9f7b6734594ee56d7f538614f602c71194db0a1af5a77f9b86eb14669fe7a8a46a2dd1b7d070b94e463f4ecd5b337c8b4d31bbf8dd5646", helloMessage.getPeerId());
}
use of org.ethereum.net.p2p.HelloMessage in project rskj by rsksmart.
the class RLPTest method testEncodeHelloMessageCap0.
// capabilities: (eth:60, bzz:0, shh:2)
@Test
public void testEncodeHelloMessageCap0() {
List<Capability> capabilities = new ArrayList<>();
capabilities.add(new Capability("eth", (byte) 0x60));
capabilities.add(new Capability("shh", (byte) 0x02));
capabilities.add(new Capability("bzz", (byte) 0x00));
HelloMessage helloMessage = new HelloMessage((byte) 4, "Geth/v0.9.29-4182e20e/windows/go1.4.2", capabilities, 30303, "a52205ce10b39be86507e28f6c3dc08ab4c3e8250e062ec47c6b7fa13cf4a4312d68d6c340315ef953ada7e19d69123a1b902ea84ec00aa5386e5d550e6c550e");
byte[] rlp = helloMessage.getEncoded();
HelloMessage helloMessage_ = new HelloMessage(rlp);
String eth = helloMessage_.getCapabilities().get(0).getName();
byte eth_60 = helloMessage_.getCapabilities().get(0).getVersion();
assertEquals("eth", eth);
assertEquals(0x60, eth_60);
String shh = helloMessage_.getCapabilities().get(1).getName();
byte shh_02 = helloMessage_.getCapabilities().get(1).getVersion();
assertEquals("shh", shh);
assertEquals(0x02, shh_02);
String bzz = helloMessage_.getCapabilities().get(2).getName();
byte bzz_00 = helloMessage_.getCapabilities().get(2).getVersion();
assertEquals("bzz", bzz);
assertEquals(0x00, bzz_00);
}
use of org.ethereum.net.p2p.HelloMessage in project rskj by rsksmart.
the class HandshakeHandler method decodeHandshake.
// consume handshake, producing no resulting message to upper layers
private void decodeHandshake(final ChannelHandlerContext ctx, ByteBuf buffer) throws Exception {
if (handshake.isInitiator()) {
if (frameCodec == null) {
byte[] responsePacket = new byte[AuthResponseMessage.getLength() + ECIESCoder.getOverhead()];
if (!buffer.isReadable(responsePacket.length)) {
return;
}
buffer.readBytes(responsePacket);
try {
// trying to decode as pre-EIP-8
AuthResponseMessage response = handshake.handleAuthResponse(myKey, initiatePacket, responsePacket);
loggerNet.trace("From: \t{} \tRecv: \t{}", ctx.channel().remoteAddress(), response);
} catch (Throwable t) {
// it must be format defined by EIP-8 then
responsePacket = readEIP8Packet(buffer, responsePacket);
if (responsePacket == null) {
return;
}
AuthResponseMessageV4 response = handshake.handleAuthResponseV4(myKey, initiatePacket, responsePacket);
loggerNet.trace("From: \t{} \tRecv: \t{}", ctx.channel().remoteAddress(), response);
}
EncryptionHandshake.Secrets secrets = this.handshake.getSecrets();
this.frameCodec = new FrameCodec(secrets);
loggerNet.trace("auth exchange done");
channel.sendHelloMessage(ctx, frameCodec, Hex.toHexString(nodeId), null);
} else {
loggerWire.debug("MessageCodec: Buffer bytes: " + buffer.readableBytes());
List<Frame> frames = frameCodec.readFrames(buffer);
if (frames == null || frames.isEmpty()) {
return;
}
Frame frame = frames.get(0);
byte[] payload = ByteStreams.toByteArray(frame.getStream());
if (frame.getType() == P2pMessageCodes.HELLO.asByte()) {
HelloMessage helloMessage = new HelloMessage(payload);
loggerNet.trace("From: \t{} \tRecv: \t{}", ctx.channel().remoteAddress(), helloMessage);
isHandshakeDone = true;
this.channel.publicRLPxHandshakeFinished(ctx, frameCodec, helloMessage);
recordSuccessfulHandshake(ctx);
} else {
DisconnectMessage message = new DisconnectMessage(payload);
loggerNet.trace("From: \t{} \tRecv: \t{}", channel, message);
channel.getNodeStatistics().nodeDisconnectedRemote(message.getReason());
}
}
} else {
loggerWire.debug("Not initiator.");
if (frameCodec == null) {
loggerWire.debug("FrameCodec == null");
byte[] authInitPacket = new byte[AuthInitiateMessage.getLength() + ECIESCoder.getOverhead()];
if (!buffer.isReadable(authInitPacket.length)) {
return;
}
buffer.readBytes(authInitPacket);
this.handshake = new EncryptionHandshake();
byte[] responsePacket;
try {
// trying to decode as pre-EIP-8
AuthInitiateMessage initiateMessage = handshake.decryptAuthInitiate(authInitPacket, myKey);
loggerNet.trace("From: \t{} \tRecv: \t{}", ctx.channel().remoteAddress(), initiateMessage);
AuthResponseMessage response = handshake.makeAuthInitiate(initiateMessage, myKey);
loggerNet.trace("To: \t{} \tSend: \t{}", ctx.channel().remoteAddress(), response);
responsePacket = handshake.encryptAuthResponse(response);
} catch (Throwable t) {
// it must be format defined by EIP-8 then
try {
authInitPacket = readEIP8Packet(buffer, authInitPacket);
if (authInitPacket == null) {
return;
}
AuthInitiateMessageV4 initiateMessage = handshake.decryptAuthInitiateV4(authInitPacket, myKey);
loggerNet.trace("From: \t{} \tRecv: \t{}", ctx.channel().remoteAddress(), initiateMessage);
AuthResponseMessageV4 response = handshake.makeAuthInitiateV4(initiateMessage, myKey);
loggerNet.trace("To: \t{} \tSend: \t{}", ctx.channel().remoteAddress(), response);
responsePacket = handshake.encryptAuthResponseV4(response);
} catch (InvalidCipherTextException ce) {
loggerNet.warn("Can't decrypt AuthInitiateMessage from " + ctx.channel().remoteAddress() + ". Most likely the remote peer used wrong public key (NodeID) to encrypt message.");
return;
}
}
handshake.agreeSecret(authInitPacket, responsePacket);
EncryptionHandshake.Secrets secrets = this.handshake.getSecrets();
this.frameCodec = new FrameCodec(secrets);
ECPoint remotePubKey = this.handshake.getRemotePublicKey();
byte[] compressed = remotePubKey.getEncoded(false);
this.remoteId = new byte[compressed.length - 1];
System.arraycopy(compressed, 1, this.remoteId, 0, this.remoteId.length);
channel.setNode(remoteId);
final ByteBuf byteBufMsg = ctx.alloc().buffer(responsePacket.length);
byteBufMsg.writeBytes(responsePacket);
ctx.writeAndFlush(byteBufMsg).sync();
} else {
List<Frame> frames = frameCodec.readFrames(buffer);
if (frames == null || frames.isEmpty()) {
return;
}
Frame frame = frames.get(0);
Message message = new P2pMessageFactory().create((byte) frame.getType(), ByteStreams.toByteArray(frame.getStream()));
loggerNet.trace("From: \t{} \tRecv: \t{}", ctx.channel().remoteAddress(), message);
if (frame.getType() == P2pMessageCodes.DISCONNECT.asByte()) {
loggerNet.info("Active remote peer disconnected right after handshake.");
return;
}
if (frame.getType() != P2pMessageCodes.HELLO.asByte()) {
throw new RuntimeException("The message type is not HELLO or DISCONNECT: " + message);
}
HelloMessage inboundHelloMessage = (HelloMessage) message;
// Secret authentication finish here
channel.sendHelloMessage(ctx, frameCodec, Hex.toHexString(nodeId), inboundHelloMessage);
isHandshakeDone = true;
this.channel.publicRLPxHandshakeFinished(ctx, frameCodec, inboundHelloMessage);
recordSuccessfulHandshake(ctx);
}
}
channel.getNodeStatistics().rlpxInHello.add();
}
use of org.ethereum.net.p2p.HelloMessage in project rskj by rsksmart.
the class Channel method sendHelloMessage.
public void sendHelloMessage(ChannelHandlerContext ctx, FrameCodec frameCodec, String nodeId, HelloMessage inboundHelloMessage) throws IOException, InterruptedException {
// in discovery mode we are supplying fake port along with fake nodeID to not receive
// incoming connections with fake public key
HelloMessage helloMessage = discoveryMode ? staticMessages.createHelloMessage(nodeId, 9) : staticMessages.createHelloMessage(nodeId);
if (inboundHelloMessage != null && P2pHandler.isProtocolVersionSupported(inboundHelloMessage.getP2PVersion())) {
// the p2p version can be downgraded if requested by peer and supported by us
helloMessage.setP2pVersion(inboundHelloMessage.getP2PVersion());
}
byte[] payload = helloMessage.getEncoded();
ByteBuf byteBufMsg = ctx.alloc().buffer();
frameCodec.writeFrame(new FrameCodec.Frame(helloMessage.getCode(), payload), byteBufMsg);
ctx.writeAndFlush(byteBufMsg).sync();
if (logger.isInfoEnabled()) {
logger.info("To: \t{} \tSend: \t{}", ctx.channel().remoteAddress(), helloMessage);
}
getNodeStatistics().rlpxOutHello.add();
}
use of org.ethereum.net.p2p.HelloMessage in project rskj by rsksmart.
the class HelloMessageTest method test2.
// Instantiate from constructor
@Test
public void test2() {
// Init
byte version = 2;
String clientStr = "Ethereum(++)/v0.7.9/Release/Linux/g++";
List<Capability> capabilities = Arrays.asList(new Capability(Capability.RSK, EthVersion.UPPER), new Capability(Capability.P2P, P2pHandler.VERSION));
int listenPort = 992;
String peerId = "1fbf1e41f08078918c9f7b6734594ee56d7f538614f602c71194db0a1af5a";
HelloMessage helloMessage = new HelloMessage(version, clientStr, capabilities, listenPort, peerId);
logger.info(helloMessage.toString());
assertEquals(P2pMessageCodes.HELLO, helloMessage.getCommand());
assertEquals(version, helloMessage.getP2PVersion());
assertEquals(clientStr, helloMessage.getClientId());
assertEquals(2, helloMessage.getCapabilities().size());
assertEquals(listenPort, helloMessage.getListenPort());
assertEquals(peerId, helloMessage.getPeerId());
}
Aggregations