Skip to content

Commit 5787934

Browse files
committed
session: add session ID to grpc metadata via context
1 parent c0fba9a commit 5787934

File tree

3 files changed

+97
-4
lines changed

3 files changed

+97
-4
lines changed

session/context.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package session
2+
3+
import (
4+
"encoding/hex"
5+
6+
"google.golang.org/grpc/metadata"
7+
)
8+
9+
type contextKey struct {
10+
name string
11+
}
12+
13+
var sessionIDCtxKey = contextKey{"lit_session_id"}
14+
15+
func FromGrpcMD(md metadata.MD) (ID, bool, error) {
16+
val := md.Get(sessionIDCtxKey.name)
17+
if len(val) == 0 {
18+
return ID{}, false, nil
19+
}
20+
21+
b, err := hex.DecodeString(val[0])
22+
if err != nil {
23+
return ID{}, false, err
24+
}
25+
26+
sessID, err := IDFromBytes(b)
27+
if err != nil {
28+
return ID{}, false, err
29+
}
30+
31+
return sessID, true, nil
32+
}
33+
34+
func AddToGrpcMD(md metadata.MD, id ID) {
35+
md.Set(sessionIDCtxKey.name, hex.EncodeToString(id[:]))
36+
}

session/server.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ import (
1818

1919
type sessionID [33]byte
2020

21-
type GRPCServerCreator func(opts ...grpc.ServerOption) *grpc.Server
21+
type GRPCServerCreator func(sessionID ID,
22+
opts ...grpc.ServerOption) *grpc.Server
2223

2324
type mailboxSession struct {
2425
server *grpc.Server
@@ -70,7 +71,7 @@ func (m *mailboxSession) start(session *Session,
7071
}
7172

7273
noiseConn := mailbox.NewNoiseGrpcConn(keys)
73-
m.server = serverCreator(grpc.Creds(noiseConn))
74+
m.server = serverCreator(session.ID, grpc.Creds(noiseConn))
7475

7576
m.wg.Add(1)
7677
go m.run(mailboxServer)

session_rpcserver.go

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"github.com/lightningnetwork/lnd/fn"
2727
"github.com/lightningnetwork/lnd/macaroons"
2828
"google.golang.org/grpc"
29+
"google.golang.org/grpc/metadata"
2930
"gopkg.in/macaroon-bakery.v2/bakery"
3031
"gopkg.in/macaroon-bakery.v2/bakery/checkers"
3132
"gopkg.in/macaroon.v2"
@@ -77,10 +78,24 @@ func newSessionRPCServer(cfg *sessionRpcServerConfig) (*sessionRpcServer,
7778
// actual mailbox server that spins up the Terminal Connect server
7879
// interface.
7980
server := session.NewServer(
80-
func(opts ...grpc.ServerOption) *grpc.Server {
81-
allOpts := append(cfg.grpcOptions, opts...)
81+
func(id session.ID, opts ...grpc.ServerOption) *grpc.Server {
82+
allOpts := []grpc.ServerOption{
83+
grpc.StreamInterceptor(
84+
addSessionIDToStreamCtx(id),
85+
),
86+
grpc.ChainUnaryInterceptor(
87+
addSessionIDToUnaryCtx(id),
88+
),
89+
}
90+
91+
allOpts = append(allOpts, cfg.grpcOptions...)
92+
allOpts = append(allOpts, opts...)
93+
94+
// Construct the gRPC server with the options.
8295
grpcServer := grpc.NewServer(allOpts...)
8396

97+
// Register various grpc servers with the LNC session
98+
// server.
8499
cfg.registerGrpcServers(grpcServer)
85100

86101
return grpcServer
@@ -94,6 +109,47 @@ func newSessionRPCServer(cfg *sessionRpcServerConfig) (*sessionRpcServer,
94109
}, nil
95110
}
96111

112+
type wrappedServerStream struct {
113+
grpc.ServerStream
114+
ctx context.Context
115+
}
116+
117+
func (w *wrappedServerStream) Context() context.Context {
118+
return w.ctx
119+
}
120+
121+
func addSessionIDToStreamCtx(id session.ID) grpc.StreamServerInterceptor {
122+
return func(srv interface{}, ss grpc.ServerStream,
123+
info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
124+
125+
md, _ := metadata.FromIncomingContext(ss.Context())
126+
mdCopy := md.Copy()
127+
session.AddToGrpcMD(mdCopy, id)
128+
129+
// Wrap the original stream with our custom context.
130+
wrapped := &wrappedServerStream{
131+
ServerStream: ss,
132+
ctx: metadata.NewIncomingContext(
133+
ss.Context(), mdCopy,
134+
),
135+
}
136+
137+
return handler(srv, wrapped)
138+
}
139+
}
140+
141+
func addSessionIDToUnaryCtx(id session.ID) grpc.UnaryServerInterceptor {
142+
return func(ctx context.Context, req any, info *grpc.UnaryServerInfo,
143+
handler grpc.UnaryHandler) (resp any, err error) {
144+
145+
md, _ := metadata.FromIncomingContext(ctx)
146+
mdCopy := md.Copy()
147+
session.AddToGrpcMD(mdCopy, id)
148+
149+
return handler(metadata.NewIncomingContext(ctx, mdCopy), req)
150+
}
151+
}
152+
97153
// start all the components necessary for the sessionRpcServer to start serving
98154
// requests. This includes resuming all non-revoked sessions.
99155
func (s *sessionRpcServer) start(ctx context.Context) error {

0 commit comments

Comments
 (0)