diff options
| author | Kyren223 <ulmliad223@gmail.com> | 2024-10-24 18:13:39 +0300 |
|---|---|---|
| committer | Kyren223 <ulmliad223@gmail.com> | 2024-10-24 18:13:39 +0300 |
| commit | a7f743f035d0f0d14400027e4781cad76503085a (patch) | |
| tree | 31c021ef76e7ca0428c5bca6b2aa2b23697f4f4c /internal/server/session/session.go | |
| parent | 688668f6d34d4d962247bd5df60c3fca61185927 (diff) | |
refactor: server split into server, session and api
Diffstat (limited to 'internal/server/session/session.go')
| -rw-r--r-- | internal/server/session/session.go | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/internal/server/session/session.go b/internal/server/session/session.go new file mode 100644 index 0000000..ff56780 --- /dev/null +++ b/internal/server/session/session.go @@ -0,0 +1,85 @@ +package session + +import ( + "context" + "crypto/ed25519" + "crypto/rand" + "net" + "sync" + "time" + + "github.com/kyren223/eko/internal/packet" + "github.com/kyren223/eko/pkg/assert" + "github.com/kyren223/eko/pkg/snowflake" +) + +type SessionManager interface { + AddSession(session *Session) + RemoveSession(id snowflake.ID) + Session(id snowflake.ID) (session *Session, ok bool) + + Node() *snowflake.Node +} + +type Session struct { + // Channel to directly write packets to the cient. + // Can be nil in cases where the connection is not available. + WriteQueue chan packet.Packet + PubKey ed25519.PublicKey + + manager SessionManager + addr *net.TCPAddr + id snowflake.ID + + mu sync.Mutex + challenge []byte + issuedTime time.Time +} + +func NewSession(manager SessionManager, addr *net.TCPAddr, id snowflake.ID, pubKey ed25519.PublicKey) *Session { + session := &Session{ + manager: manager, + addr: addr, + PubKey: pubKey, + WriteQueue: make(chan packet.Packet, 10), + challenge: make([]byte, 32), // Recommended nonce size + } + session.Challenge() // Make sure an initial nonce is generated + return session +} + +func (s *Session) Addr() *net.TCPAddr { + return s.addr +} + +func (s *Session) ID() snowflake.ID { + return s.id +} + +func (s *Session) Manager() SessionManager { + return s.manager +} + +func (s *Session) Challenge() []byte { + s.mu.Lock() + defer s.mu.Unlock() + if time.Since(s.issuedTime) > time.Minute { + s.issuedTime = time.Now() + _, err := rand.Read(s.challenge) + assert.NoError(err, "random should always produce a value") + } + return s.challenge +} + +type key struct{} + +var sessKey key + +func NewContext(ctx context.Context, sess *Session) context.Context { + return context.WithValue(ctx, sessKey, sess) +} + +func FromContext(ctx context.Context) (*Session, bool) { + sess, ok := ctx.Value(sessKey).(*Session) + return sess, ok +} |
