public override SSUState HandleMessage(SSUHeader header, BufRefLen reader) { var tstime = SSUHost.SSUDateTime(header.TimeStamp); if (header.MessageType != SSUHeader.MessageTypes.SessionCreated) { #if LOG_ALL_TRANSPORT Logging.LogTransport("SSU SessionRequestState: Received unexpected message " + tstime.ToString() + " : " + header.Flag.ToString()); #endif return(this); } SCMessage = new SessionCreated(reader, Session.RemoteRouter.Certificate); Session.RelayTag = SCMessage.RelayTag; Y = new I2PPublicKey((BufRefLen)SCMessage.Y, Session.RemoteRouter.Certificate); BufUtils.DHI2PToSessionAndMAC(out Session.SharedKey, out Session.MACKey, Y.ToBigInteger().ModPow(PrivateKey.ToBigInteger(), I2PConstants.ElGamalP)); var ipaddr = new IPAddress(SCMessage.Address.ToByteArray()); ushort port = SCMessage.Port.PeekFlip16(0); Session.SignOnTimeB = SCMessage.SignOnTime.Peek32(0); var btime = SSUHost.SSUDateTime(BufUtils.Flip32(Session.SignOnTimeB)); #if LOG_ALL_TRANSPORT Logging.LogTransport("SSU SessionRequestState " + Session.DebugId + " : Received SessionCreated. " + tstime.ToString() + " : " + btime.ToString()); #endif Session.Host.ReportedAddress(ipaddr); if (!I2PSignature.SupportedSignatureType(Session.RemoteRouter.Certificate.SignatureType)) { throw new SignatureCheckFailureException("SSU SessionRequestState " + Session.DebugId + " : " + "Received non supported signature type: " + Session.RemoteRouter.Certificate.SignatureType.ToString()); } var cipher = new CbcBlockCipher(new AesEngine()); cipher.Init(false, Session.SharedKey.ToParametersWithIV(header.IV)); cipher.ProcessBytes(SCMessage.SignatureEncrBuf); var baddr = new BufLen(Session.RemoteEP.Address.GetAddressBytes()); var sign = new I2PSignature((BufRefLen)SCMessage.Signature, Session.RemoteRouter.Certificate); var sok = I2PSignature.DoVerify( Session.RemoteRouter.SigningPublicKey, sign, X.Key, Y.Key, SCMessage.Address, SCMessage.Port, baddr, BufUtils.Flip16BL((ushort)Session.RemoteEP.Port), SCMessage.RelayTag, SCMessage.SignOnTime); #if LOG_ALL_TRANSPORT Logging.LogTransport("SSU SessionRequestState: Signature check: " + sok.ToString() + ". " + Session.RemoteRouter.Certificate.SignatureType.ToString()); #endif if (!sok) { throw new SignatureCheckFailureException("SSU SessionRequestState " + Session.DebugId + ": Received SessionCreated signature check failed." + Session.RemoteRouter.Certificate.ToString()); } var relaytag = SCMessage.RelayTag.PeekFlip32(0); if (relaytag != 0) { Session.Host.IntroductionRelayOffered( new IntroducerInfo( Session.RemoteEP.Address, (ushort)Session.RemoteEP.Port, Session.IntroKey, relaytag)); } Logging.LogTransport("SSU SessionRequestState: Session " + Session.DebugId + " created. Moving to SessionConfirmedState."); Session.ReportConnectionEstablished(); return(new SessionConfirmedState(Session, this)); }
public override SSUState HandleMessage(SSUHeader header, BufRefLen reader) { DataSent(); #if LOG_ALL_TRANSPORT DebugUtils.Log("SSU EstablishedState +" + Session.TransportInstance.ToString() + "+ received: " + header.MessageType.ToString() + ": " + SSUHost.SSUDateTime(header.TimeStamp).ToString()); #endif switch (header.MessageType) { case SSUHeader.MessageTypes.Data: try { var datamsg = new SSUDataMessage(reader, Session.Defragmenter); if (datamsg.ExplicitAcks != null) { Session.Fragmenter.GotAck(datamsg.ExplicitAcks); } if (datamsg.AckBitfields != null) { Session.Fragmenter.GotAck(datamsg.AckBitfields); } if (datamsg.NewMessages != null) { foreach (var msg in datamsg.NewMessages) { var i2npmsg = I2NPMessage.ReadHeader5((BufRefLen)msg.GetPayload()); #if LOG_ALL_TRANSPORT DebugUtils.Log("SSU EstablishedState +" + Session.TransportInstance.ToString() + "+ complete message " + msg.MessageId.ToString() + ": " + i2npmsg.Expiration.ToString()); #endif if (i2npmsg.MessageType == I2PCore.Tunnel.I2NP.Messages.I2NPMessage.MessageTypes.DeliveryStatus) { if (((DeliveryStatusMessage)i2npmsg.Message).IsNetworkId((ulong)I2PConstants.I2P_NETWORK_ID)) { continue; } } Session.MessageReceived(i2npmsg); } } } catch (Exception ex) { DebugUtils.Log("EstablishedState: SSUHost.SSUMessageTypes.Data", ex); } break; case SSUHeader.MessageTypes.SessionDestroyed: DebugUtils.LogDebug(() => string.Format("SSU EstablishedState {0}: SessionDestroyed received.", Session.DebugId)); SendSessionDestroyed(); return(null); case SSUHeader.MessageTypes.PeerTest: HandleIncomingPeerTestPackage(reader); break; case SSUHeader.MessageTypes.RelayResponse: DebugUtils.LogDebug(() => string.Format("SSU EstablishedState {0}: RelayResponse received from {1}.", Session.DebugId, Session.RemoteEP)); var response = new RelayResponse(reader); Session.Host.ReportRelayResponse(header, response, Session.RemoteEP); break; case SSUHeader.MessageTypes.RelayIntro: var intro = new RelayIntro(reader); DebugUtils.LogDebug(() => $"SSU EstablishedState {Session.DebugId}: RelayIntro received from {Session.RemoteEP} for {intro.AliceEndpoint}."); Session.Host.Send(intro.AliceEndpoint, new BufLen(new byte[0])); break; case SSUHeader.MessageTypes.RelayRequest: // if ( !SSUHost.IntroductionSupported ) throw new Exception( "SSU relay introduction not supported" ); DebugUtils.LogDebug(() => string.Format("SSU EstablishedState {0}: Relay introduction not supported.", Session.DebugId)); break; case SSUHeader.MessageTypes.SessionRequest: DebugUtils.LogDebug(() => string.Format("SSU EstablishedState {0}: SessionRequest received. Ending session.", Session.DebugId)); SendSessionDestroyed(); return(null); default: DebugUtils.LogDebug(() => string.Format("SSU EstablishedState {0}: Unexpected message received: {1}.", Session.DebugId, header.MessageType)); break; } return(this); }