mirror of
https://github.com/go-i2p/go-i2p.git
synced 2025-06-30 19:53:23 -04:00
160 lines
4.6 KiB
Go
160 lines
4.6 KiB
Go
package noise
|
|
|
|
import (
|
|
"net"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/sirupsen/logrus"
|
|
|
|
cb "github.com/emirpasic/gods/queues/circularbuffer"
|
|
"github.com/flynn/noise"
|
|
"github.com/samber/oops"
|
|
|
|
"github.com/go-i2p/go-i2p/lib/common/router_info"
|
|
"github.com/go-i2p/go-i2p/lib/transport"
|
|
)
|
|
|
|
type NoiseSession struct {
|
|
router_info.RouterInfo
|
|
*noise.CipherState
|
|
*sync.Cond
|
|
*NoiseTransport // The parent transport, which "Dialed" the connection to the peer with whom we established the session
|
|
*HandshakeState
|
|
RecvQueue *cb.Queue
|
|
SendQueue *cb.Queue
|
|
VerifyCallback VerifyCallbackFunc
|
|
activeCall int32
|
|
Conn net.Conn
|
|
}
|
|
|
|
// RemoteAddr implements net.Conn
|
|
func (noise_session *NoiseSession) RemoteAddr() net.Addr {
|
|
log.WithField("remote_addr", noise_session.RouterInfo.String()).Debug("Getting RemoteAddr")
|
|
return &noise_session.RouterInfo
|
|
}
|
|
|
|
// SetDeadline implements net.Conn
|
|
func (noise_session *NoiseSession) SetDeadline(t time.Time) error {
|
|
log.WithField("deadline", t).Debug("Setting deadline")
|
|
return noise_session.Conn.SetDeadline(t)
|
|
}
|
|
|
|
// SetReadDeadline implements net.Conn
|
|
func (noise_session *NoiseSession) SetReadDeadline(t time.Time) error {
|
|
log.WithField("read_deadline", t).Debug("Setting read deadline")
|
|
return noise_session.Conn.SetReadDeadline(t)
|
|
}
|
|
|
|
// SetWriteDeadline implements net.Conn
|
|
func (noise_session *NoiseSession) SetWriteDeadline(t time.Time) error {
|
|
log.WithField("write_deadline", t).Debug("Setting write deadline")
|
|
return noise_session.Conn.SetWriteDeadline(t)
|
|
}
|
|
|
|
var (
|
|
exampleNoiseSession transport.TransportSession = &NoiseSession{}
|
|
ExampleNoiseSession net.Conn = exampleNoiseSession.(*NoiseSession)
|
|
)
|
|
|
|
func (s *NoiseSession) LocalAddr() net.Addr {
|
|
localAddr := s.Conn.LocalAddr()
|
|
log.WithField("local_addr", localAddr.String()).Debug("Getting LocalAddr")
|
|
return s.Conn.LocalAddr()
|
|
}
|
|
|
|
func (s *NoiseSession) Close() error {
|
|
log.Debug("Closing NoiseSession")
|
|
s.SendQueue.Clear()
|
|
s.RecvQueue.Clear()
|
|
log.Debug("SendQueue and RecvQueue cleared")
|
|
return nil
|
|
}
|
|
|
|
func (c *NoiseSession) processCallback(publicKey []byte, payload []byte) error {
|
|
log.WithFields(logrus.Fields{
|
|
"public_key_length": len(publicKey),
|
|
"payload_length": len(payload),
|
|
}).Debug("Processing callback")
|
|
|
|
if c.VerifyCallback == nil {
|
|
log.Debug("VerifyCallback is nil, skipping verification")
|
|
return nil
|
|
}
|
|
err := c.VerifyCallback(publicKey, payload)
|
|
if err != nil {
|
|
log.WithError(err).Error("VerifyCallback failed")
|
|
} else {
|
|
log.Debug("VerifyCallback succeeded")
|
|
}
|
|
return err
|
|
}
|
|
|
|
// PeerStaticKey is equal to the NTCP2 peer's static public key, found in their router info
|
|
func (s *NoiseSession) peerStaticKey() ([32]byte, error) {
|
|
for _, addr := range s.RouterInfo.RouterAddresses() {
|
|
transportStyle, err := addr.TransportStyle().Data()
|
|
if err != nil {
|
|
continue
|
|
}
|
|
if transportStyle == NOISE_PROTOCOL_NAME {
|
|
return addr.StaticKey()
|
|
}
|
|
}
|
|
return [32]byte{}, oops.Errorf("Remote static key error")
|
|
}
|
|
|
|
func (s *NoiseSession) peerStaticIV() ([16]byte, error) {
|
|
for _, addr := range s.RouterInfo.RouterAddresses() {
|
|
transportStyle, err := addr.TransportStyle().Data()
|
|
if err != nil {
|
|
continue
|
|
}
|
|
if transportStyle == NOISE_PROTOCOL_NAME {
|
|
return addr.InitializationVector()
|
|
}
|
|
}
|
|
return [16]byte{}, oops.Errorf("Remote static IV error")
|
|
}
|
|
|
|
// newBlock allocates a new packet, from hc's free list if possible.
|
|
func newBlock() []byte {
|
|
// return make([]byte, MaxPayloadSize)
|
|
block := make([]byte, MaxPayloadSize)
|
|
log.WithField("block_size", MaxPayloadSize).Debug("Created new block")
|
|
return block
|
|
}
|
|
|
|
type VerifyCallbackFunc func(publicKey []byte, data []byte) error
|
|
|
|
func NewNoiseTransportSession(ri router_info.RouterInfo) (transport.TransportSession, error) {
|
|
log.WithField("router_info", ri.String()).Debug("Creating new NoiseTransportSession")
|
|
// socket, err := DialNoise("noise", ri)
|
|
for _, addr := range ri.RouterAddresses() {
|
|
log.WithField("address", string(addr.Bytes())).Debug("Attempting to dial")
|
|
socket, err := net.Dial("tcp", string(addr.Bytes()))
|
|
if err != nil {
|
|
log.WithError(err).Error("Failed to dial address")
|
|
return nil, err
|
|
}
|
|
session := &NoiseSession{
|
|
SendQueue: cb.New(1024),
|
|
RecvQueue: cb.New(1024),
|
|
RouterInfo: ri,
|
|
Conn: socket,
|
|
}
|
|
log.WithField("local_addr", socket.LocalAddr().String()).Debug("NoiseTransportSession created successfully")
|
|
return session, nil
|
|
}
|
|
log.Error("Failed to create NoiseTransportSession, all addresses failed")
|
|
return nil, oops.Errorf("Transport constructor error")
|
|
}
|
|
|
|
func NewNoiseSession(ri router_info.RouterInfo) (*NoiseSession, error) {
|
|
ns, err := NewNoiseTransportSession(ri)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return ns.(*NoiseSession), err
|
|
}
|