From 2d401a7dce4523fa7c96d4a5dddf350e5f5d28bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Papp?= Date: Thu, 19 Jun 2025 16:22:59 +0200 Subject: [PATCH] Add signal message --- client/internal/conn_mgr.go | 22 ++++---- client/internal/engine.go | 11 +++- client/internal/lazyconn/manager/manager.go | 45 ++++++++++++---- client/internal/peer/conn.go | 6 ++- client/internal/peer/signaler.go | 10 ++++ client/internal/peerstore/store.go | 13 ++++- signal/proto/signalexchange.pb.go | 58 +++++++++++---------- signal/proto/signalexchange.proto | 3 +- 8 files changed, 117 insertions(+), 51 deletions(-) diff --git a/client/internal/conn_mgr.go b/client/internal/conn_mgr.go index aac312dc3..edd2a163b 100644 --- a/client/internal/conn_mgr.go +++ b/client/internal/conn_mgr.go @@ -201,7 +201,7 @@ func (e *ConnMgr) RemovePeerConn(peerKey string) { if !ok { return } - defer conn.Close() + defer conn.Close(false) if !e.isStartedWithLazyMgr() { return @@ -211,23 +211,25 @@ func (e *ConnMgr) RemovePeerConn(peerKey string) { conn.Log.Infof("removed peer from lazy conn manager") } -func (e *ConnMgr) OnSignalMsg(ctx context.Context, peerKey string) (*peer.Conn, bool) { - conn, ok := e.peerStore.PeerConn(peerKey) - if !ok { - return nil, false - } - +func (e *ConnMgr) ActivatePeer(ctx context.Context, conn *peer.Conn) { if !e.isStartedWithLazyMgr() { - return conn, true + return } - if found := e.lazyConnMgr.ActivatePeer(e.lazyCtx, peerKey); found { + if found := e.lazyConnMgr.ActivatePeer(e.lazyCtx, conn.GetKey()); found { conn.Log.Infof("activated peer from inactive state") if err := conn.Open(ctx); err != nil { conn.Log.Errorf("failed to open connection: %v", err) } } - return conn, true +} + +func (e *ConnMgr) DeactivatePeer(conn *peer.Conn) { + if !e.isStartedWithLazyMgr() { + return + } + + e.lazyConnMgr.DeactivatePeer(conn.ConnID()) } func (e *ConnMgr) Close() { diff --git a/client/internal/engine.go b/client/internal/engine.go index 253ecb2a6..a71f78237 100644 --- a/client/internal/engine.go +++ b/client/internal/engine.go @@ -1255,7 +1255,7 @@ func (e *Engine) addNewPeer(peerConfig *mgmProto.RemotePeerConfig) error { } if exists := e.connMgr.AddPeerConn(e.ctx, peerKey, conn); exists { - conn.Close() + conn.Close(false) return fmt.Errorf("peer already exists: %s", peerKey) } @@ -1331,11 +1331,16 @@ func (e *Engine) receiveSignalEvents() { e.syncMsgMux.Lock() defer e.syncMsgMux.Unlock() - conn, ok := e.connMgr.OnSignalMsg(e.ctx, msg.Key) + conn, ok := e.peerStore.PeerConn(msg.Key) if !ok { return fmt.Errorf("wrongly addressed message %s", msg.Key) } + msgType := msg.GetBody().GetType() + if msgType != sProto.Body_GO_IDLE { + e.connMgr.ActivatePeer(e.ctx, conn) + } + switch msg.GetBody().Type { case sProto.Body_OFFER: remoteCred, err := signal.UnMarshalCredential(msg) @@ -1392,6 +1397,8 @@ func (e *Engine) receiveSignalEvents() { go conn.OnRemoteCandidate(candidate, e.routeManager.GetClientRoutes()) case sProto.Body_MODE: + case sProto.Body_GO_IDLE: + e.connMgr.DeactivatePeer(conn) } return nil diff --git a/client/internal/lazyconn/manager/manager.go b/client/internal/lazyconn/manager/manager.go index 52825f8f7..672bb62ac 100644 --- a/client/internal/lazyconn/manager/manager.go +++ b/client/internal/lazyconn/manager/manager.go @@ -143,7 +143,7 @@ func (m *Manager) Start(ctx context.Context) { case <-ctx.Done(): return case peerConnID := <-m.activityManager.OnActivityChan: - m.onPeerActivity(ctx, peerConnID) + m.onPeerActivity(peerConnID) case peerIDs := <-m.inactivityManager.InactivePeersChan: for _, peerID := range peerIDs { m.onPeerInactivityTimedOut(peerID) @@ -265,15 +265,42 @@ func (m *Manager) ActivatePeer(ctx context.Context, peerID string) (found bool) return false } - if !m.activateSinglePeer(ctx, cfg, mp) { + if !m.activateSinglePeer(cfg, mp) { return false } - m.activateHAGroupPeers(ctx, peerID) + m.activateHAGroupPeers(peerID) return true } +func (m *Manager) DeactivatePeer(peerID peerid.ConnID) { + m.managedPeersMu.Lock() + defer m.managedPeersMu.Unlock() + + mp, ok := m.managedPeersByConnID[peerID] + if !ok { + return + } + + if mp.expectedWatcher != watcherInactivity { + return + } + + m.peerStore.PeerConnClose(mp.peerCfg.PublicKey) + + mp.peerCfg.Log.Infof("start activity monitor") + + mp.expectedWatcher = watcherActivity + + m.inactivityManager.RemovePeer(mp.peerCfg.PublicKey) + + if err := m.activityManager.MonitorPeerActivity(*mp.peerCfg); err != nil { + mp.peerCfg.Log.Errorf("failed to create activity monitor: %v", err) + return + } +} + // getPeerForActivation checks if a peer can be activated and returns the necessary structs // Returns nil values if the peer should be skipped func (m *Manager) getPeerForActivation(peerID string) (*lazyconn.PeerConfig, *managedPeer) { @@ -296,7 +323,7 @@ func (m *Manager) getPeerForActivation(peerID string) (*lazyconn.PeerConfig, *ma } // activateSinglePeer activates a single peer (internal method) -func (m *Manager) activateSinglePeer(ctx context.Context, cfg *lazyconn.PeerConfig, mp *managedPeer) bool { +func (m *Manager) activateSinglePeer(cfg *lazyconn.PeerConfig, mp *managedPeer) bool { mp.expectedWatcher = watcherInactivity m.activityManager.RemovePeer(cfg.Log, cfg.PeerConnID) @@ -308,7 +335,7 @@ func (m *Manager) activateSinglePeer(ctx context.Context, cfg *lazyconn.PeerConf } // activateHAGroupPeers activates all peers in HA groups that the given peer belongs to -func (m *Manager) activateHAGroupPeers(ctx context.Context, triggerPeerID string) { +func (m *Manager) activateHAGroupPeers(triggerPeerID string) { m.routesMu.RLock() haGroups := m.peerToHAGroups[triggerPeerID] m.routesMu.RUnlock() @@ -334,7 +361,7 @@ func (m *Manager) activateHAGroupPeers(ctx context.Context, triggerPeerID string continue } - if m.activateSinglePeer(ctx, cfg, mp) { + if m.activateSinglePeer(cfg, mp) { activatedCount++ cfg.Log.Infof("activated peer as part of HA group %s (triggered by %s)", haGroup, triggerPeerID) m.peerStore.PeerConnOpen(m.engineCtx, cfg.PublicKey) @@ -398,7 +425,7 @@ func (m *Manager) close() { log.Infof("lazy connection manager closed") } -func (m *Manager) onPeerActivity(ctx context.Context, peerConnID peerid.ConnID) { +func (m *Manager) onPeerActivity(peerConnID peerid.ConnID) { m.managedPeersMu.Lock() defer m.managedPeersMu.Unlock() @@ -415,11 +442,11 @@ func (m *Manager) onPeerActivity(ctx context.Context, peerConnID peerid.ConnID) mp.peerCfg.Log.Infof("detected peer activity") - if !m.activateSinglePeer(ctx, mp.peerCfg, mp) { + if !m.activateSinglePeer(mp.peerCfg, mp) { return } - m.activateHAGroupPeers(ctx, mp.peerCfg.PublicKey) + m.activateHAGroupPeers(mp.peerCfg.PublicKey) m.peerStore.PeerConnOpen(m.engineCtx, mp.peerCfg.PublicKey) } diff --git a/client/internal/peer/conn.go b/client/internal/peer/conn.go index b33023873..1e77e70c5 100644 --- a/client/internal/peer/conn.go +++ b/client/internal/peer/conn.go @@ -226,7 +226,7 @@ func (conn *Conn) Open(engineCtx context.Context) error { } // Close closes this peer Conn issuing a close event to the Conn closeCh -func (conn *Conn) Close() { +func (conn *Conn) Close(graceful bool) { conn.mu.Lock() defer conn.wgWatcherWg.Wait() defer conn.mu.Unlock() @@ -236,6 +236,10 @@ func (conn *Conn) Close() { return } + if graceful { + conn.signaler.SignalIdle(conn.config.Key) + } + conn.Log.Infof("close peer connection") conn.ctxCancel() diff --git a/client/internal/peer/signaler.go b/client/internal/peer/signaler.go index 713123e5d..9022e0299 100644 --- a/client/internal/peer/signaler.go +++ b/client/internal/peer/signaler.go @@ -68,3 +68,13 @@ func (s *Signaler) signalOfferAnswer(offerAnswer OfferAnswer, remoteKey string, return nil } + +func (s *Signaler) SignalIdle(remoteKey string) error { + return s.signal.Send(&sProto.Message{ + Key: s.wgPrivateKey.PublicKey().String(), + RemoteKey: remoteKey, + Body: &sProto.Body{ + Type: sProto.Body_GO_IDLE, + }, + }) +} diff --git a/client/internal/peerstore/store.go b/client/internal/peerstore/store.go index 81ac7a5b6..099fe4528 100644 --- a/client/internal/peerstore/store.go +++ b/client/internal/peerstore/store.go @@ -95,6 +95,17 @@ func (s *Store) PeerConnOpen(ctx context.Context, pubKey string) { } +func (s *Store) PeerConnIdle(pubKey string) { + s.peerConnsMu.RLock() + defer s.peerConnsMu.RUnlock() + + p, ok := s.peerConns[pubKey] + if !ok { + return + } + p.Close(true) +} + func (s *Store) PeerConnClose(pubKey string) { s.peerConnsMu.RLock() defer s.peerConnsMu.RUnlock() @@ -103,7 +114,7 @@ func (s *Store) PeerConnClose(pubKey string) { if !ok { return } - p.Close() + p.Close(false) } func (s *Store) PeersPubKey() []string { diff --git a/signal/proto/signalexchange.pb.go b/signal/proto/signalexchange.pb.go index 30f704c6f..3d45dea69 100644 --- a/signal/proto/signalexchange.pb.go +++ b/signal/proto/signalexchange.pb.go @@ -29,6 +29,7 @@ const ( Body_ANSWER Body_Type = 1 Body_CANDIDATE Body_Type = 2 Body_MODE Body_Type = 4 + Body_GO_IDLE Body_Type = 5 ) // Enum value maps for Body_Type. @@ -38,12 +39,14 @@ var ( 1: "ANSWER", 2: "CANDIDATE", 4: "MODE", + 5: "GO_IDLE", } Body_Type_value = map[string]int32{ "OFFER": 0, "ANSWER": 1, "CANDIDATE": 2, "MODE": 4, + "GO_IDLE": 5, } ) @@ -225,7 +228,7 @@ type Body struct { FeaturesSupported []uint32 `protobuf:"varint,6,rep,packed,name=featuresSupported,proto3" json:"featuresSupported,omitempty"` // RosenpassConfig is a Rosenpass config of the remote peer our peer tries to connect to RosenpassConfig *RosenpassConfig `protobuf:"bytes,7,opt,name=rosenpassConfig,proto3" json:"rosenpassConfig,omitempty"` - // relayServerAddress is an IP:port of the relay server + // relayServerAddress is url of the relay server RelayServerAddress string `protobuf:"bytes,8,opt,name=relayServerAddress,proto3" json:"relayServerAddress,omitempty"` } @@ -440,7 +443,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, 0xa6, 0x03, 0x0a, 0x04, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x2d, + 0x04, 0x62, 0x6f, 0x64, 0x79, 0x22, 0xb3, 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, @@ -463,33 +466,34 @@ 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, 0x36, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, + 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, 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, + 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, } var ( diff --git a/signal/proto/signalexchange.proto b/signal/proto/signalexchange.proto index 4431edd7c..b04d6ef28 100644 --- a/signal/proto/signalexchange.proto +++ b/signal/proto/signalexchange.proto @@ -47,6 +47,7 @@ message Body { ANSWER = 1; CANDIDATE = 2; MODE = 4; + GO_IDLE = 5; } Type type = 1; string payload = 2; @@ -74,4 +75,4 @@ message RosenpassConfig { bytes rosenpassPubKey = 1; // rosenpassServerAddr is an IP:port of the rosenpass service string rosenpassServerAddr = 2; -} \ No newline at end of file +}