mirror of
https://github.com/go-i2p/go-sam-go.git
synced 2025-06-16 22:10:48 -04:00
123 lines
2.4 KiB
Go
123 lines
2.4 KiB
Go
package stream
|
|
|
|
import (
|
|
"net"
|
|
"time"
|
|
|
|
"github.com/samber/oops"
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
// Read reads data from the connection
|
|
func (c *StreamConn) Read(b []byte) (int, error) {
|
|
c.mu.RLock()
|
|
if c.closed {
|
|
c.mu.RUnlock()
|
|
return 0, oops.Errorf("connection is closed")
|
|
}
|
|
conn := c.conn
|
|
c.mu.RUnlock()
|
|
|
|
n, err := conn.Read(b)
|
|
if err != nil {
|
|
log.WithFields(logrus.Fields{
|
|
"local": c.laddr.Base32(),
|
|
"remote": c.raddr.Base32(),
|
|
}).WithError(err).Debug("Read error")
|
|
}
|
|
return n, err
|
|
}
|
|
|
|
// Write writes data to the connection
|
|
func (c *StreamConn) Write(b []byte) (int, error) {
|
|
c.mu.RLock()
|
|
if c.closed {
|
|
c.mu.RUnlock()
|
|
return 0, oops.Errorf("connection is closed")
|
|
}
|
|
conn := c.conn
|
|
c.mu.RUnlock()
|
|
|
|
n, err := conn.Write(b)
|
|
if err != nil {
|
|
log.WithFields(logrus.Fields{
|
|
"local": c.laddr.Base32(),
|
|
"remote": c.raddr.Base32(),
|
|
}).WithError(err).Debug("Write error")
|
|
}
|
|
return n, err
|
|
}
|
|
|
|
// Close closes the connection
|
|
func (c *StreamConn) Close() error {
|
|
c.mu.Lock()
|
|
defer c.mu.Unlock()
|
|
|
|
if c.closed {
|
|
return nil
|
|
}
|
|
|
|
logger := log.WithFields(logrus.Fields{
|
|
"local": c.laddr.Base32(),
|
|
"remote": c.raddr.Base32(),
|
|
})
|
|
logger.Debug("Closing StreamConn")
|
|
|
|
c.closed = true
|
|
|
|
if c.conn != nil {
|
|
err := c.conn.Close()
|
|
if err != nil {
|
|
logger.WithError(err).Error("Failed to close underlying connection")
|
|
return oops.Errorf("failed to close connection: %w", err)
|
|
}
|
|
}
|
|
|
|
logger.Debug("Successfully closed StreamConn")
|
|
return nil
|
|
}
|
|
|
|
// LocalAddr returns the local network address
|
|
func (c *StreamConn) LocalAddr() net.Addr {
|
|
return &i2pAddr{addr: c.laddr}
|
|
}
|
|
|
|
// RemoteAddr returns the remote network address
|
|
func (c *StreamConn) RemoteAddr() net.Addr {
|
|
return &i2pAddr{addr: c.raddr}
|
|
}
|
|
|
|
// SetDeadline sets the read and write deadlines
|
|
func (c *StreamConn) SetDeadline(t time.Time) error {
|
|
if err := c.SetReadDeadline(t); err != nil {
|
|
return err
|
|
}
|
|
return c.SetWriteDeadline(t)
|
|
}
|
|
|
|
// SetReadDeadline sets the deadline for future Read calls
|
|
func (c *StreamConn) SetReadDeadline(t time.Time) error {
|
|
c.mu.RLock()
|
|
conn := c.conn
|
|
c.mu.RUnlock()
|
|
|
|
if conn == nil {
|
|
return oops.Errorf("connection is nil")
|
|
}
|
|
|
|
return conn.SetReadDeadline(t)
|
|
}
|
|
|
|
// SetWriteDeadline sets the deadline for future Write calls
|
|
func (c *StreamConn) SetWriteDeadline(t time.Time) error {
|
|
c.mu.RLock()
|
|
conn := c.conn
|
|
c.mu.RUnlock()
|
|
|
|
if conn == nil {
|
|
return oops.Errorf("connection is nil")
|
|
}
|
|
|
|
return conn.SetWriteDeadline(t)
|
|
}
|