mirror of
https://github.com/go-i2p/go-i2p.git
synced 2025-06-16 22:10:48 -04:00
Move to SessionProcessors
This commit is contained in:
@ -1,14 +1,100 @@
|
||||
package ntcp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/go-i2p/go-i2p/lib/crypto/types"
|
||||
"github.com/go-i2p/go-i2p/lib/transport/ntcp/handshake"
|
||||
"github.com/go-i2p/go-i2p/lib/transport/ntcp/messages"
|
||||
"github.com/samber/oops"
|
||||
)
|
||||
|
||||
// PerformInboundHandshake handles a handshake initiated by a remote peer
|
||||
func (c *NTCP2Session) PerformInboundHandshake(conn net.Conn, localKey types.PrivateKey) (*handshake.HandshakeState, error) {
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
// PerformIncomingHandshake conducts the NTCP2 handshake as the responder (server).
|
||||
// It performs the server side of the 3-message handshake sequence:
|
||||
// 1. Receives and processes SessionRequest (Message 1)
|
||||
// 2. Creates and sends SessionCreated (Message 2)
|
||||
// 3. Receives and processes SessionConfirmed (Message 3)
|
||||
// After successful completion, the session is established and ready for data exchange.
|
||||
func (s *NTCP2Session) PerformIncomingHandshake(conn net.Conn) error {
|
||||
// Initialize processors if not already done
|
||||
if s.Processors == nil {
|
||||
s.Processors = make(map[messages.MessageType]handshake.HandshakeMessageProcessor)
|
||||
s.Processors[messages.MessageTypeSessionRequest] = &SessionRequestProcessor{NTCP2Session: s}
|
||||
s.Processors[messages.MessageTypeSessionCreated] = &SessionCreatedProcessor{NTCP2Session: s}
|
||||
s.Processors[messages.MessageTypeSessionConfirmed] = &SessionConfirmedProcessor{NTCP2Session: s}
|
||||
}
|
||||
|
||||
// Step 1: Process SessionRequest (Message 1) from initiator
|
||||
requestProcessor, err := s.GetProcessor(messages.MessageTypeSessionRequest)
|
||||
if err != nil {
|
||||
return oops.Errorf("failed to get session request processor: %w", err)
|
||||
}
|
||||
|
||||
// Read and decode SessionRequest message
|
||||
requestMsg, err := requestProcessor.ReadMessage(conn, s.HandshakeState.(*handshake.HandshakeState))
|
||||
if err != nil {
|
||||
return oops.Errorf("failed to read session request message: %w", err)
|
||||
}
|
||||
|
||||
// Process SessionRequest to update handshake state
|
||||
if err := requestProcessor.ProcessMessage(requestMsg, s.HandshakeState.(*handshake.HandshakeState)); err != nil {
|
||||
return oops.Errorf("failed to process session request message: %w", err)
|
||||
}
|
||||
|
||||
// Step 2: Create and send SessionCreated (Message 2)
|
||||
createdProcessor, err := s.GetProcessor(messages.MessageTypeSessionCreated)
|
||||
if err != nil {
|
||||
return oops.Errorf("failed to get session created processor: %w", err)
|
||||
}
|
||||
|
||||
// Create SessionCreated message
|
||||
createdMsg, err := createdProcessor.CreateMessage(s.HandshakeState.(*handshake.HandshakeState))
|
||||
if err != nil {
|
||||
return oops.Errorf("failed to create session created message: %w", err)
|
||||
}
|
||||
|
||||
// Obfuscate ephemeral key
|
||||
obfuscatedKey, err := createdProcessor.ObfuscateKey(createdMsg, s.HandshakeState.(*handshake.HandshakeState))
|
||||
if err != nil {
|
||||
return oops.Errorf("failed to obfuscate ephemeral key: %w", err)
|
||||
}
|
||||
|
||||
// Encrypt payload
|
||||
encryptedPayload, err := createdProcessor.EncryptPayload(
|
||||
createdMsg,
|
||||
obfuscatedKey,
|
||||
s.HandshakeState.(*handshake.HandshakeState),
|
||||
)
|
||||
if err != nil {
|
||||
return oops.Errorf("failed to encrypt session created payload: %w", err)
|
||||
}
|
||||
|
||||
// Write SessionCreated to connection
|
||||
if err := s.writeMessageToConn(
|
||||
conn,
|
||||
obfuscatedKey,
|
||||
encryptedPayload,
|
||||
createdProcessor.GetPadding(createdMsg),
|
||||
); err != nil {
|
||||
return oops.Errorf("failed to write session created message: %w", err)
|
||||
}
|
||||
|
||||
// Step 3: Process SessionConfirmed (Message 3) from initiator
|
||||
confirmedProcessor, err := s.GetProcessor(messages.MessageTypeSessionConfirmed)
|
||||
if err != nil {
|
||||
return oops.Errorf("failed to get session confirmed processor: %w", err)
|
||||
}
|
||||
|
||||
// Read and decode SessionConfirmed message
|
||||
confirmedMsg, err := confirmedProcessor.ReadMessage(conn, s.HandshakeState.(*handshake.HandshakeState))
|
||||
if err != nil {
|
||||
return oops.Errorf("failed to read session confirmed message: %w", err)
|
||||
}
|
||||
|
||||
// Process SessionConfirmed to finalize handshake state
|
||||
if err := confirmedProcessor.ProcessMessage(confirmedMsg, s.HandshakeState.(*handshake.HandshakeState)); err != nil {
|
||||
return oops.Errorf("failed to process session confirmed message: %w", err)
|
||||
}
|
||||
|
||||
// Handshake complete, mark session as established
|
||||
return s.HandshakeState.CompleteHandshake()
|
||||
}
|
||||
|
@ -8,20 +8,28 @@ import (
|
||||
"github.com/samber/oops"
|
||||
)
|
||||
|
||||
// PerformClientHandshake performs the NTCP2 handshake as a client
|
||||
// PerformOutboundHandshake conducts the NTCP2 handshake as the initiator (client).
|
||||
// It performs the full 3-message handshake sequence:
|
||||
// 1. Creates and sends SessionRequest (Message 1)
|
||||
// 2. Receives and processes SessionCreated (Message 2)
|
||||
// 3. Creates and sends SessionConfirmed (Message 3)
|
||||
// After successful completion, the session is established and ready for data exchange.
|
||||
func (s *NTCP2Session) PerformOutboundHandshake(conn net.Conn) error {
|
||||
// Initialize processors if not already done
|
||||
if s.Processors == nil {
|
||||
s.CreateHandshakeProcessors()
|
||||
s.Processors = make(map[messages.MessageType]handshake.HandshakeMessageProcessor)
|
||||
s.Processors[messages.MessageTypeSessionRequest] = &SessionRequestProcessor{NTCP2Session: s}
|
||||
s.Processors[messages.MessageTypeSessionCreated] = &SessionCreatedProcessor{NTCP2Session: s}
|
||||
s.Processors[messages.MessageTypeSessionConfirmed] = &SessionConfirmedProcessor{NTCP2Session: s}
|
||||
}
|
||||
|
||||
// Get request processor
|
||||
// Step 1: Get SessionRequest processor and create Message 1
|
||||
requestProcessor, err := s.GetProcessor(messages.MessageTypeSessionRequest)
|
||||
if err != nil {
|
||||
return oops.Errorf("failed to get session request processor: %w", err)
|
||||
}
|
||||
|
||||
// Create message
|
||||
// Create and prepare SessionRequest
|
||||
msg, err := requestProcessor.CreateMessage(s.HandshakeState.(*handshake.HandshakeState))
|
||||
if err != nil {
|
||||
return oops.Errorf("failed to create session request: %w", err)
|
||||
@ -30,24 +38,77 @@ func (s *NTCP2Session) PerformOutboundHandshake(conn net.Conn) error {
|
||||
// Obfuscate ephemeral key
|
||||
obfuscatedKey, err := requestProcessor.ObfuscateKey(msg, s.HandshakeState.(*handshake.HandshakeState))
|
||||
if err != nil {
|
||||
return oops.Errorf("failed to obfuscate key: %w", err)
|
||||
return oops.Errorf("failed to obfuscate ephemeral key: %w", err)
|
||||
}
|
||||
|
||||
// Encrypt payload
|
||||
// Encrypt options payload
|
||||
encryptedPayload, err := requestProcessor.EncryptPayload(msg, obfuscatedKey, s.HandshakeState.(*handshake.HandshakeState))
|
||||
if err != nil {
|
||||
return oops.Errorf("failed to encrypt payload: %w", err)
|
||||
return oops.Errorf("failed to encrypt session request payload: %w", err)
|
||||
}
|
||||
|
||||
// Write to connection
|
||||
// Write complete SessionRequest message to connection
|
||||
if err := s.writeMessageToConn(conn, obfuscatedKey, encryptedPayload, requestProcessor.GetPadding(msg)); err != nil {
|
||||
return oops.Errorf("failed to write session request: %w", err)
|
||||
}
|
||||
|
||||
// Continue with rest of handshake for SessionCreated and SessionConfirmed messages
|
||||
// Similar pattern for each message
|
||||
// Step 2: Process SessionCreated (Message 2) from responder
|
||||
createdProcessor, err := s.GetProcessor(messages.MessageTypeSessionCreated)
|
||||
if err != nil {
|
||||
return oops.Errorf("failed to get session created processor: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
// Read and decode SessionCreated message
|
||||
createdMsg, err := createdProcessor.ReadMessage(conn, s.HandshakeState.(*handshake.HandshakeState))
|
||||
if err != nil {
|
||||
return oops.Errorf("failed to read session created message: %w", err)
|
||||
}
|
||||
|
||||
// Process SessionCreated to update handshake state
|
||||
if err := createdProcessor.ProcessMessage(createdMsg, s.HandshakeState.(*handshake.HandshakeState)); err != nil {
|
||||
return oops.Errorf("failed to process session created message: %w", err)
|
||||
}
|
||||
|
||||
// Step 3: Create and send SessionConfirmed (Message 3)
|
||||
confirmedProcessor, err := s.GetProcessor(messages.MessageTypeSessionConfirmed)
|
||||
if err != nil {
|
||||
return oops.Errorf("failed to get session confirmed processor: %w", err)
|
||||
}
|
||||
|
||||
// Create SessionConfirmed message
|
||||
confirmedMsg, err := confirmedProcessor.CreateMessage(s.HandshakeState.(*handshake.HandshakeState))
|
||||
if err != nil {
|
||||
return oops.Errorf("failed to create session confirmed message: %w", err)
|
||||
}
|
||||
|
||||
// Obfuscate static key
|
||||
obfuscatedStaticKey, err := confirmedProcessor.ObfuscateKey(confirmedMsg, s.HandshakeState.(*handshake.HandshakeState))
|
||||
if err != nil {
|
||||
return oops.Errorf("failed to obfuscate static key: %w", err)
|
||||
}
|
||||
|
||||
// Encrypt RouterInfo payload
|
||||
encryptedConfirmedPayload, err := confirmedProcessor.EncryptPayload(
|
||||
confirmedMsg,
|
||||
obfuscatedStaticKey,
|
||||
s.HandshakeState.(*handshake.HandshakeState),
|
||||
)
|
||||
if err != nil {
|
||||
return oops.Errorf("failed to encrypt session confirmed payload: %w", err)
|
||||
}
|
||||
|
||||
// Write SessionConfirmed to connection
|
||||
if err := s.writeMessageToConn(
|
||||
conn,
|
||||
obfuscatedStaticKey,
|
||||
encryptedConfirmedPayload,
|
||||
confirmedProcessor.GetPadding(confirmedMsg),
|
||||
); err != nil {
|
||||
return oops.Errorf("failed to write session confirmed message: %w", err)
|
||||
}
|
||||
|
||||
// Handshake complete, mark session as established
|
||||
return s.HandshakeState.CompleteHandshake()
|
||||
}
|
||||
|
||||
// Helper to write message parts to connection
|
||||
|
Reference in New Issue
Block a user