From b0c95d9bd2ed3384bc9380b332afb28bafa933cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Papp?= Date: Mon, 4 Aug 2025 20:17:11 +0200 Subject: [PATCH] Enhance ICE handshake with session ID management and improve message handling --- client/internal/engine.go | 42 ++++++---------- client/internal/peer/conn.go | 1 - client/internal/peer/handshaker.go | 43 ++++++++--------- client/internal/peer/signaler.go | 3 +- client/internal/peer/worker_ice.go | 33 +++++++++++-- signal/client/client.go | 3 +- signal/client/grpc.go | 77 ++++++++++++++++++++---------- signal/client/worker.go | 57 ++++++++++++++++++++++ signal/proto/signalexchange.pb.go | 70 ++++++++++++++++----------- signal/proto/signalexchange.proto | 2 + 10 files changed, 220 insertions(+), 111 deletions(-) create mode 100644 signal/client/worker.go diff --git a/client/internal/engine.go b/client/internal/engine.go index a3192188b..a1aaad27b 100644 --- a/client/internal/engine.go +++ b/client/internal/engine.go @@ -1336,19 +1336,21 @@ func (e *Engine) receiveSignalEvents() { } switch msg.GetBody().Type { - case sProto.Body_OFFER: + case sProto.Body_OFFER, sProto.Body_ANSWER: remoteCred, err := signal.UnMarshalCredential(msg) if err != nil { return err } - var rosenpassPubKey []byte - rosenpassAddr := "" - if msg.GetBody().GetRosenpassConfig() != nil { - rosenpassPubKey = msg.GetBody().GetRosenpassConfig().GetRosenpassPubKey() - rosenpassAddr = msg.GetBody().GetRosenpassConfig().GetRosenpassServerAddr() + var ( + rosenpassPubKey []byte + rosenpassAddr string + ) + if cfg := msg.GetBody().GetRosenpassConfig(); cfg != nil { + rosenpassPubKey = cfg.GetRosenpassPubKey() + rosenpassAddr = cfg.GetRosenpassServerAddr() } - conn.OnRemoteOffer(peer.OfferAnswer{ + offerAnswer := peer.OfferAnswer{ IceCredentials: peer.IceCredentials{ UFrag: remoteCred.UFrag, Pwd: remoteCred.Pwd, @@ -1358,30 +1360,14 @@ func (e *Engine) receiveSignalEvents() { RosenpassPubKey: rosenpassPubKey, RosenpassAddr: rosenpassAddr, RelaySrvAddress: msg.GetBody().GetRelayServerAddress(), - }) - case sProto.Body_ANSWER: - remoteCred, err := signal.UnMarshalCredential(msg) - if err != nil { - return err + SessionID: msg.GetBody().SessionId, } - var rosenpassPubKey []byte - rosenpassAddr := "" - if msg.GetBody().GetRosenpassConfig() != nil { - rosenpassPubKey = msg.GetBody().GetRosenpassConfig().GetRosenpassPubKey() - rosenpassAddr = msg.GetBody().GetRosenpassConfig().GetRosenpassServerAddr() + if msg.Body.Type == sProto.Body_OFFER { + conn.OnRemoteOffer(offerAnswer) + } else { + conn.OnRemoteAnswer(offerAnswer) } - conn.OnRemoteAnswer(peer.OfferAnswer{ - IceCredentials: peer.IceCredentials{ - UFrag: remoteCred.UFrag, - Pwd: remoteCred.Pwd, - }, - WgListenPort: int(msg.GetBody().GetWgListenPort()), - Version: msg.GetBody().GetNetBirdVersion(), - RosenpassPubKey: rosenpassPubKey, - RosenpassAddr: rosenpassAddr, - RelaySrvAddress: msg.GetBody().GetRelayServerAddress(), - }) case sProto.Body_CANDIDATE: candidate, err := ice.UnmarshalCandidate(msg.GetBody().Payload) if err != nil { diff --git a/client/internal/peer/conn.go b/client/internal/peer/conn.go index b22cf5e8a..d4fe9b517 100644 --- a/client/internal/peer/conn.go +++ b/client/internal/peer/conn.go @@ -548,7 +548,6 @@ func (conn *Conn) onRelayDisconnected() { } func (conn *Conn) onGuardEvent() { - conn.Log.Debugf("send offer to peer") conn.dumpState.SendOffer() if err := conn.handshaker.SendOffer(); err != nil { conn.Log.Errorf("failed to send offer: %v", err) diff --git a/client/internal/peer/handshaker.go b/client/internal/peer/handshaker.go index 234c91133..31fb9ba03 100644 --- a/client/internal/peer/handshaker.go +++ b/client/internal/peer/handshaker.go @@ -4,6 +4,7 @@ import ( "context" "errors" "sync" + "time" log "github.com/sirupsen/logrus" @@ -39,6 +40,11 @@ type OfferAnswer struct { // relay server address RelaySrvAddress string + // SessionID is the unique identifier of the session, used to discard old messages + SessionID *int64 + + // for debugging purposes + When time.Time } type Handshaker struct { @@ -133,42 +139,35 @@ func (h *Handshaker) sendOffer() error { return ErrSignalIsNotReady } - iceUFrag, icePwd := h.ice.GetLocalUserCredentials() - offer := OfferAnswer{ - IceCredentials: IceCredentials{iceUFrag, icePwd}, - WgListenPort: h.config.LocalWgPort, - Version: version.NetbirdVersion(), - RosenpassPubKey: h.config.RosenpassConfig.PubKey, - RosenpassAddr: h.config.RosenpassConfig.Addr, - } - - addr, err := h.relay.RelayInstanceAddress() - if err == nil { - offer.RelaySrvAddress = addr - } + offer := h.buildOfferAnswer() + h.log.Infof("sending offer: %s, %d", offer.When, offer.SessionID) return h.signaler.SignalOffer(offer, h.config.Key) } func (h *Handshaker) sendAnswer() error { - h.log.Infof("sending answer") - uFrag, pwd := h.ice.GetLocalUserCredentials() + answer := h.buildOfferAnswer() + h.log.Infof("sending answer: %s, serial: %d", answer.When, answer.SessionID) + return h.signaler.SignalAnswer(answer, h.config.Key) +} + +func (h *Handshaker) buildOfferAnswer() OfferAnswer { + uFrag, pwd := h.ice.GetLocalUserCredentials() + sid := h.ice.SessionID() answer := OfferAnswer{ IceCredentials: IceCredentials{uFrag, pwd}, WgListenPort: h.config.LocalWgPort, Version: version.NetbirdVersion(), RosenpassPubKey: h.config.RosenpassConfig.PubKey, RosenpassAddr: h.config.RosenpassConfig.Addr, + When: time.Now(), + SessionID: &sid, } - addr, err := h.relay.RelayInstanceAddress() - if err == nil { + + if addr, err := h.relay.RelayInstanceAddress(); err == nil { answer.RelaySrvAddress = addr } - if err = h.signaler.SignalAnswer(answer, h.config.Key); err != nil { - return err - } - - return nil + return answer } diff --git a/client/internal/peer/signaler.go b/client/internal/peer/signaler.go index 9022e0299..ed8d2ae74 100644 --- a/client/internal/peer/signaler.go +++ b/client/internal/peer/signaler.go @@ -56,7 +56,8 @@ func (s *Signaler) signalOfferAnswer(offerAnswer OfferAnswer, remoteKey string, bodyType, offerAnswer.RosenpassPubKey, offerAnswer.RosenpassAddr, - offerAnswer.RelaySrvAddress) + offerAnswer.RelaySrvAddress, + *offerAnswer.SessionID) if err != nil { return err } diff --git a/client/internal/peer/worker_ice.go b/client/internal/peer/worker_ice.go index cfa78c9e4..9b1f6c0fe 100644 --- a/client/internal/peer/worker_ice.go +++ b/client/internal/peer/worker_ice.go @@ -46,7 +46,14 @@ type WorkerICE struct { agentDialerCancel context.CancelFunc agentConnecting bool // while it is true, drop all incoming offers lastSuccess time.Time // with this avoid the too frequent ICE agent recreation - muxAgent sync.Mutex + // remoteSessionID represents the peer's session identifier from the latest remote offer. + remoteSessionID int64 + // sessionID is used to track the current session ID of the ICE agent + // increase by one when disconnecting the agent + // with it the remote peer can discard the already deprecated offer/answer + // Without it the remote peer may recreate a workable ICE connection + sessionID int64 + muxAgent sync.Mutex StunTurn []*stun.URI @@ -70,6 +77,7 @@ func NewWorkerICE(ctx context.Context, log *log.Entry, config ConnConfig, conn * statusRecorder: statusRecorder, hasRelayOnLocally: hasRelayOnLocally, lastKnownState: ice.ConnectionStateDisconnected, + sessionID: 0, } localUfrag, localPwd, err := icemaker.GenerateICECredentials() @@ -82,7 +90,7 @@ func NewWorkerICE(ctx context.Context, log *log.Entry, config ConnConfig, conn * } func (w *WorkerICE) OnNewOffer(remoteOfferAnswer *OfferAnswer) { - w.log.Debugf("OnNewOffer for ICE") + w.log.Debugf("OnNewOffer for ICE: %s, %s, serial: %d", time.Since(remoteOfferAnswer.When), remoteOfferAnswer.When, remoteOfferAnswer.SessionID) w.muxAgent.Lock() if w.agentConnecting { @@ -92,8 +100,13 @@ func (w *WorkerICE) OnNewOffer(remoteOfferAnswer *OfferAnswer) { } if w.agent != nil { - if time.Since(w.lastSuccess) < 900*time.Millisecond { - w.log.Debugf("agent is already connected, skipping the offer") + // backward compatibility with old clients that do not send session ID + if remoteOfferAnswer.SessionID == nil { + w.log.Debugf("agent already exists, skipping the offer") + w.muxAgent.Unlock() + return + } + if w.remoteSessionID == *remoteOfferAnswer.SessionID { w.muxAgent.Unlock() return } @@ -194,6 +207,13 @@ func (w *WorkerICE) reCreateAgent(dialerCancel context.CancelFunc, candidates [] return agent, nil } +func (w *WorkerICE) SessionID() int64 { + w.muxAgent.Lock() + defer w.muxAgent.Unlock() + + return w.sessionID +} + // will block until connection succeeded // but it won't release if ICE Agent went into Disconnected or Failed state, // so we have to cancel it with the provided context once agent detected a broken connection @@ -241,9 +261,13 @@ func (w *WorkerICE) connect(ctx context.Context, agent *ice.Agent, remoteOfferAn } w.log.Debugf("on ICE conn is ready to use") + w.log.Infof("connection successed with offer session: %d", remoteOfferAnswer.SessionID) w.muxAgent.Lock() w.agentConnecting = false w.lastSuccess = time.Now() + if remoteOfferAnswer.SessionID != nil { + w.remoteSessionID = *remoteOfferAnswer.SessionID + } w.muxAgent.Unlock() // todo: the potential problem is a race between the onConnectionStateChange @@ -257,6 +281,7 @@ func (w *WorkerICE) closeAgent(agent *ice.Agent, cancel context.CancelFunc) { } w.muxAgent.Lock() + w.sessionID++ if w.agent == agent { w.agent = nil w.agentConnecting = false diff --git a/signal/client/client.go b/signal/client/client.go index eff1ccb87..cca69a862 100644 --- a/signal/client/client.go +++ b/signal/client/client.go @@ -52,7 +52,7 @@ func UnMarshalCredential(msg *proto.Message) (*Credential, error) { } // MarshalCredential marshal a Credential instance and returns a Message object -func MarshalCredential(myKey wgtypes.Key, myPort int, remoteKey string, credential *Credential, t proto.Body_Type, rosenpassPubKey []byte, rosenpassAddr string, relaySrvAddress string) (*proto.Message, error) { +func MarshalCredential(myKey wgtypes.Key, myPort int, remoteKey string, credential *Credential, t proto.Body_Type, rosenpassPubKey []byte, rosenpassAddr string, relaySrvAddress string, sessionID int64) (*proto.Message, error) { return &proto.Message{ Key: myKey.PublicKey().String(), RemoteKey: remoteKey, @@ -66,6 +66,7 @@ func MarshalCredential(myKey wgtypes.Key, myPort int, remoteKey string, credenti RosenpassServerAddr: rosenpassAddr, }, RelayServerAddress: relaySrvAddress, + SessionId: &sessionID, }, }, nil } diff --git a/signal/client/grpc.go b/signal/client/grpc.go index 2ff84e460..28df8f04f 100644 --- a/signal/client/grpc.go +++ b/signal/client/grpc.go @@ -45,19 +45,10 @@ type GrpcClient struct { connStateCallbackLock sync.RWMutex onReconnectedListenerFn func() -} -func (c *GrpcClient) StreamConnected() bool { - return c.status == StreamConnected -} - -func (c *GrpcClient) GetStatus() Status { - return c.status -} - -// Close Closes underlying connections to the Signal Exchange -func (c *GrpcClient) Close() error { - return c.signalConn.Close() + decryptionWorker *Worker + decryptionWorkerCancel context.CancelFunc + decryptionWg sync.WaitGroup } // NewClient creates a new Signal client @@ -93,6 +84,25 @@ func NewClient(ctx context.Context, addr string, key wgtypes.Key, tlsEnabled boo }, nil } +func (c *GrpcClient) StreamConnected() bool { + return c.status == StreamConnected +} + +func (c *GrpcClient) GetStatus() Status { + return c.status +} + +// Close Closes underlying connections to the Signal Exchange +func (c *GrpcClient) Close() error { + if c.decryptionWorkerCancel != nil { + c.decryptionWorkerCancel() + } + c.decryptionWg.Wait() + c.decryptionWorker = nil + + return c.signalConn.Close() +} + // SetConnStateListener set the ConnStateNotifier func (c *GrpcClient) SetConnStateListener(notifier ConnStateNotifier) { c.connStateCallbackLock.Lock() @@ -148,8 +158,12 @@ func (c *GrpcClient) Receive(ctx context.Context, msgHandler func(msg *proto.Mes log.Infof("connected to the Signal Service stream") c.notifyConnected() + + // Start worker pool if not already started + c.startEncryptionWorker(ctx, msgHandler) + // start receiving messages from the Signal stream (from other peers through signal) - err = c.receive(stream, msgHandler) + err = c.receive(stream) if err != nil { if s, ok := status.FromError(err); ok && s.Code() == codes.Canceled { log.Debugf("signal connection context has been canceled, this usually indicates shutdown") @@ -174,6 +188,7 @@ func (c *GrpcClient) Receive(ctx context.Context, msgHandler func(msg *proto.Mes return nil } + func (c *GrpcClient) notifyStreamDisconnected() { c.mux.Lock() defer c.mux.Unlock() @@ -382,11 +397,11 @@ func (c *GrpcClient) Send(msg *proto.Message) error { } // receive receives messages from other peers coming through the Signal Exchange -func (c *GrpcClient) receive(stream proto.SignalExchange_ConnectStreamClient, - msgHandler func(msg *proto.Message) error) error { - +// and distributes them to worker threads for processing +func (c *GrpcClient) receive(stream proto.SignalExchange_ConnectStreamClient) error { for { msg, err := stream.Recv() + // Handle errors immediately switch s, ok := status.FromError(err); { case ok && s.Code() == codes.Canceled: log.Debugf("stream canceled (usually indicates shutdown)") @@ -398,24 +413,36 @@ func (c *GrpcClient) receive(stream proto.SignalExchange_ConnectStreamClient, log.Debugf("Signal Service stream closed by server") return err case err != nil: + log.Errorf("Stream receive error: %v", err) return err } - log.Tracef("received a new message from Peer [fingerprint: %s]", msg.Key) - decryptedMessage, err := c.decryptMessage(msg) - if err != nil { - log.Errorf("failed decrypting message of Peer [key: %s] error: [%s]", msg.Key, err.Error()) + if msg == nil { + continue } - err = msgHandler(decryptedMessage) - - if err != nil { - log.Errorf("error while handling message of Peer [key: %s] error: [%s]", msg.Key, err.Error()) - // todo send something?? + if err := c.decryptionWorker.AddMsg(msg); err != nil { + log.Errorf("failed to add message to decryption worker: %v", err) } } } +func (c *GrpcClient) startEncryptionWorker(ctx context.Context, handler func(msg *proto.Message) error) { + if c.decryptionWorker != nil { + return + } + + c.decryptionWorker = NewWorker(c.decryptMessage, handler) + c.decryptionWg.Add(1) + go func() { + workerCtx, workerCancel := context.WithCancel(ctx) + defer workerCancel() + + c.decryptionWorker.Work(workerCtx) + c.decryptionWg.Done() + }() +} + func (c *GrpcClient) notifyDisconnected(err error) { c.connStateCallbackLock.RLock() defer c.connStateCallbackLock.RUnlock() diff --git a/signal/client/worker.go b/signal/client/worker.go new file mode 100644 index 000000000..1a8656b1e --- /dev/null +++ b/signal/client/worker.go @@ -0,0 +1,57 @@ +package client + +import ( + "context" + "fmt" + + log "github.com/sirupsen/logrus" + + "github.com/netbirdio/netbird/signal/proto" +) + +type Worker struct { + decryptMessage func(msg *proto.EncryptedMessage) (*proto.Message, error) + handler func(msg *proto.Message) error + + encryptedMsgPool chan *proto.EncryptedMessage +} + +func NewWorker(decryptFn func(msg *proto.EncryptedMessage) (*proto.Message, error), handlerFn func(msg *proto.Message) error) *Worker { + return &Worker{ + decryptMessage: decryptFn, + handler: handlerFn, + encryptedMsgPool: make(chan *proto.EncryptedMessage, 1), + } +} + +func (w *Worker) AddMsg(msg *proto.EncryptedMessage) error { + if w.encryptedMsgPool == nil { + return fmt.Errorf("worker is not initialized") + } + + // this is blocker because do not want to drop messages here + w.encryptedMsgPool <- msg + return nil +} + +func (w *Worker) Work(ctx context.Context) { + for { + select { + case msg := <-w.encryptedMsgPool: + decryptedMessage, err := w.decryptMessage(msg) + if err != nil { + log.Errorf("failed to decrypt message: %v", err) + continue + } + + if err := w.handler(decryptedMessage); err != nil { + log.Errorf("failed to handle message: %v", err) + continue + } + + case <-ctx.Done(): + log.Debugf("Message worker stopping due to context cancellation") + return + } + } +} diff --git a/signal/proto/signalexchange.pb.go b/signal/proto/signalexchange.pb.go index 3d45dea69..cf488a8e1 100644 --- a/signal/proto/signalexchange.pb.go +++ b/signal/proto/signalexchange.pb.go @@ -230,6 +230,7 @@ type Body struct { RosenpassConfig *RosenpassConfig `protobuf:"bytes,7,opt,name=rosenpassConfig,proto3" json:"rosenpassConfig,omitempty"` // relayServerAddress is url of the relay server RelayServerAddress string `protobuf:"bytes,8,opt,name=relayServerAddress,proto3" json:"relayServerAddress,omitempty"` + SessionId *int64 `protobuf:"varint,9,opt,name=sessionId,proto3,oneof" json:"sessionId,omitempty"` } func (x *Body) Reset() { @@ -320,6 +321,13 @@ func (x *Body) GetRelayServerAddress() string { return "" } +func (x *Body) GetSessionId() int64 { + if x != nil && x.SessionId != nil { + return *x.SessionId + } + return 0 +} + // Mode indicates a connection mode type Mode struct { state protoimpl.MessageState @@ -443,7 +451,7 @@ var file_signalexchange_proto_rawDesc = []byte{ 0x52, 0x09, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x28, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x65, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x42, 0x6f, 0x64, 0x79, 0x52, - 0x04, 0x62, 0x6f, 0x64, 0x79, 0x22, 0xb3, 0x03, 0x0a, 0x04, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x2d, + 0x04, 0x62, 0x6f, 0x64, 0x79, 0x22, 0xe4, 0x03, 0x0a, 0x04, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x2d, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x65, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x42, 0x6f, 0x64, 0x79, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, @@ -466,34 +474,37 @@ var file_signalexchange_proto_rawDesc = []byte{ 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2e, 0x0a, 0x12, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x43, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, - 0x0a, 0x05, 0x4f, 0x46, 0x46, 0x45, 0x52, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x41, 0x4e, 0x53, - 0x57, 0x45, 0x52, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x41, 0x4e, 0x44, 0x49, 0x44, 0x41, - 0x54, 0x45, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x4d, 0x4f, 0x44, 0x45, 0x10, 0x04, 0x12, 0x0b, - 0x0a, 0x07, 0x47, 0x4f, 0x5f, 0x49, 0x44, 0x4c, 0x45, 0x10, 0x05, 0x22, 0x2e, 0x0a, 0x04, 0x4d, - 0x6f, 0x64, 0x65, 0x12, 0x1b, 0x0a, 0x06, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x06, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x88, 0x01, 0x01, - 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x22, 0x6d, 0x0a, 0x0f, 0x52, - 0x6f, 0x73, 0x65, 0x6e, 0x70, 0x61, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x28, - 0x0a, 0x0f, 0x72, 0x6f, 0x73, 0x65, 0x6e, 0x70, 0x61, 0x73, 0x73, 0x50, 0x75, 0x62, 0x4b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x72, 0x6f, 0x73, 0x65, 0x6e, 0x70, 0x61, - 0x73, 0x73, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x13, 0x72, 0x6f, 0x73, 0x65, - 0x6e, 0x70, 0x61, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x72, 0x6f, 0x73, 0x65, 0x6e, 0x70, 0x61, 0x73, 0x73, - 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x32, 0xb9, 0x01, 0x0a, 0x0e, 0x53, - 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x45, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x4c, 0x0a, - 0x04, 0x53, 0x65, 0x6e, 0x64, 0x12, 0x20, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x65, 0x78, - 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x20, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, - 0x65, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, - 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x59, 0x0a, 0x0d, 0x43, - 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x20, 0x2e, 0x73, - 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x65, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x45, 0x6e, - 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x20, - 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x65, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, - 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0x08, 0x5a, 0x06, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x21, 0x0a, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x49, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x09, 0x73, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x88, 0x01, 0x01, 0x22, 0x43, 0x0a, 0x04, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x09, 0x0a, 0x05, 0x4f, 0x46, 0x46, 0x45, 0x52, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, + 0x41, 0x4e, 0x53, 0x57, 0x45, 0x52, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x41, 0x4e, 0x44, + 0x49, 0x44, 0x41, 0x54, 0x45, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x4d, 0x4f, 0x44, 0x45, 0x10, + 0x04, 0x12, 0x0b, 0x0a, 0x07, 0x47, 0x4f, 0x5f, 0x49, 0x44, 0x4c, 0x45, 0x10, 0x05, 0x42, 0x0c, + 0x0a, 0x0a, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x2e, 0x0a, 0x04, + 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x1b, 0x0a, 0x06, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x06, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x88, 0x01, + 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x22, 0x6d, 0x0a, 0x0f, + 0x52, 0x6f, 0x73, 0x65, 0x6e, 0x70, 0x61, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, + 0x28, 0x0a, 0x0f, 0x72, 0x6f, 0x73, 0x65, 0x6e, 0x70, 0x61, 0x73, 0x73, 0x50, 0x75, 0x62, 0x4b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x72, 0x6f, 0x73, 0x65, 0x6e, 0x70, + 0x61, 0x73, 0x73, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x13, 0x72, 0x6f, 0x73, + 0x65, 0x6e, 0x70, 0x61, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x72, 0x6f, 0x73, 0x65, 0x6e, 0x70, 0x61, 0x73, + 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x32, 0xb9, 0x01, 0x0a, 0x0e, + 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x45, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x4c, + 0x0a, 0x04, 0x53, 0x65, 0x6e, 0x64, 0x12, 0x20, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x65, + 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, + 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x20, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, + 0x6c, 0x65, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, + 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x59, 0x0a, 0x0d, + 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x20, 0x2e, + 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x65, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x45, + 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, + 0x20, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x65, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0x08, 0x5a, 0x06, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -601,6 +612,7 @@ func file_signalexchange_proto_init() { } } } + file_signalexchange_proto_msgTypes[2].OneofWrappers = []interface{}{} file_signalexchange_proto_msgTypes[3].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ diff --git a/signal/proto/signalexchange.proto b/signal/proto/signalexchange.proto index b04d6ef28..18fc008f8 100644 --- a/signal/proto/signalexchange.proto +++ b/signal/proto/signalexchange.proto @@ -64,6 +64,8 @@ message Body { // relayServerAddress is url of the relay server string relayServerAddress = 8; + + optional int64 sessionId = 9; } // Mode indicates a connection mode