Files
go-sam-go/common/new.go

74 lines
2.3 KiB
Go
Raw Normal View History

2025-02-17 22:23:20 -05:00
package common
import (
"net"
"strings"
"github.com/samber/oops"
2025-02-17 22:23:20 -05:00
)
2025-05-27 19:59:02 -04:00
// NewSAM creates a new SAM instance by connecting to the specified address,
// performing the hello handshake, and initializing the SAM resolver.
// It returns a pointer to the SAM instance or an error if any step fails.
// This function combines connection establishment and hello handshake into a single step,
// eliminating the need for separate helper functions.
// It also initializes the SAM resolver directly after the connection is established.
// The SAM instance is ready to use for further operations like session creation or name resolution.
2025-02-17 22:23:20 -05:00
func NewSAM(address string) (*SAM, error) {
logger := log.WithField("address", address)
logger.Debug("Creating new SAM instance")
2025-05-27 19:59:02 -04:00
// Inline connection establishment - eliminates connectToSAM helper
conn, err := net.Dial("tcp", address)
2025-02-17 22:23:20 -05:00
if err != nil {
logger.WithError(err).Error("Failed to connect to SAM bridge")
2025-05-27 19:59:02 -04:00
return nil, oops.Errorf("failed to connect to SAM bridge at %s: %w", address, err)
2025-02-17 22:23:20 -05:00
}
s := &SAM{
Conn: conn,
}
2025-05-27 19:59:02 -04:00
// Inline hello handshake - eliminates sendHelloAndValidate helper
if _, err := conn.Write(s.SAMEmit.HelloBytes()); err != nil {
logger.WithError(err).Error("Failed to send hello message")
conn.Close()
return nil, oops.Errorf("failed to send hello message: %w", err)
}
buf := make([]byte, 256)
n, err := conn.Read(buf)
if err != nil {
logger.WithError(err).Error("Failed to read SAM response")
conn.Close()
return nil, oops.Errorf("failed to read SAM response: %w", err)
}
response := string(buf[:n])
switch {
case strings.Contains(response, HELLO_REPLY_OK):
logger.Debug("SAM hello successful")
case response == HELLO_REPLY_NOVERSION:
logger.Error("SAM bridge does not support SAMv3")
conn.Close()
return nil, oops.Errorf("SAM bridge does not support SAMv3")
default:
logger.WithField("response", response).Error("Unexpected SAM response")
conn.Close()
2025-05-27 19:59:02 -04:00
return nil, oops.Errorf("unexpected SAM response: %s", response)
2025-02-17 22:23:20 -05:00
}
s.SAMEmit.I2PConfig.SetSAMAddress(address)
2025-05-27 16:46:29 -04:00
resolver, err := NewSAMResolver(s)
if err != nil {
logger.WithError(err).Error("Failed to create SAM resolver")
conn.Close()
return nil, oops.Errorf("failed to create SAM resolver: %w", err)
2025-02-17 22:23:20 -05:00
}
2025-05-27 16:46:29 -04:00
s.SAMResolver = *resolver
logger.Debug("Successfully created new SAM instance")
2025-02-17 22:23:20 -05:00
return s, nil
}