99 "net/http"
1010 "regexp"
1111 "strings"
12+ "sync"
1213
1314 "github.com/btcsuite/btcd/btcec/v2"
1415 "github.com/golang/protobuf/proto"
9091
9192 m = make (map [string ]* mobileClient )
9293
94+ mMutex sync.Mutex
95+
9396 registry = make (map [string ]func (context.Context ,
9497 * grpc.ClientConn , string , func (string , error )))
9598
99102// InitLNC sets up everything required for LNC to run including
100103// signal interceptor, logs, and an instance of the mobile client.
101104func InitLNC (namespace , debugLevel string ) error {
105+ mMutex .Lock ()
106+ defer mMutex .Unlock ()
107+
102108 // only initialize interceptor and logs on first connection
103109 if ! interceptorLogsInitialize {
104110 // set debug level to 'info' if not specified
@@ -138,6 +144,9 @@ func InitLNC(namespace, debugLevel string) error {
138144func ConnectServer (namespace string , mailboxServer string , isDevServer bool ,
139145 pairingPhrase string , localStatic string , remoteStatic string ) error {
140146
147+ mMutex .Lock ()
148+ defer mMutex .Unlock ()
149+
141150 // Check that the correct arguments and config combinations have been
142151 // provided.
143152 err := validateArgs (mailboxServer , localStatic , remoteStatic )
@@ -211,11 +220,16 @@ func ConnectServer(namespace string, mailboxServer string, isDevServer bool,
211220
212221// IsConnected returns whether or not there is an active connection.
213222func IsConnected (namespace string ) bool {
223+ mMutex .Lock ()
224+ defer mMutex .Unlock ()
214225 return m [namespace ].lndConn != nil
215226}
216227
217228// Disconnect closes the RPC connection.
218229func Disconnect (namespace string ) {
230+ mMutex .Lock ()
231+ defer mMutex .Unlock ()
232+
219233 if m [namespace ].lndConn != nil {
220234 if err := m [namespace ].lndConn .Close (); err != nil {
221235 log .Errorf ("Error closing RPC connection: %v" , err )
@@ -226,6 +240,9 @@ func Disconnect(namespace string) {
226240
227241// Status returns the status of the LNC RPC connection.
228242func Status (namespace string ) string {
243+ mMutex .Lock ()
244+ defer mMutex .Unlock ()
245+
229246 if m [namespace ].statusChecker == nil {
230247 return ""
231248 }
@@ -236,25 +253,34 @@ func Status(namespace string) string {
236253// RegisterLocalPrivCreateCallback sets up the native callbacks upon
237254// creation of local private key.
238255func RegisterLocalPrivCreateCallback (namespace string , c NativeCallback ) {
256+ mMutex .Lock ()
257+ defer mMutex .Unlock ()
239258 m [namespace ].localPrivCreateCallback = c
240259}
241260
242261// RegisterRemoteKeyReceiveCallback sets up the native callbacks upon
243262// receiving the remote key from the server.
244263func RegisterRemoteKeyReceiveCallback (namespace string , c NativeCallback ) {
264+ mMutex .Lock ()
265+ defer mMutex .Unlock ()
245266 m [namespace ].remoteKeyReceiveCallback = c
246267}
247268
248269// RegisterAuthDataCallback sets up the native callbacks upon
249270// receiving auth data.
250271func RegisterAuthDataCallback (namespace string , c NativeCallback ) {
272+ mMutex .Lock ()
273+ defer mMutex .Unlock ()
251274 m [namespace ].authDataCallback = c
252275}
253276
254277// InvokeRPC makes a synchronous RPC call.
255278func InvokeRPC (namespace string , rpcName string , requestJSON string ,
256279 c NativeCallback ) error {
257280
281+ mMutex .Lock ()
282+ defer mMutex .Unlock ()
283+
258284 if rpcName == "" {
259285 return fmt .Errorf ("param rpcName required" )
260286 }
@@ -291,6 +317,9 @@ func InvokeRPC(namespace string, rpcName string, requestJSON string,
291317
292318// GetExpiry returns the expiration time of the connection macaroon.
293319func GetExpiry (namespace string ) (string , error ) {
320+ mMutex .Lock ()
321+ defer mMutex .Unlock ()
322+
294323 if m [namespace ].mac == nil {
295324 return "" , fmt .Errorf ("macaroon not obtained yet. GetExpiry should " +
296325 "only be called once the connection is complete" )
@@ -306,6 +335,9 @@ func GetExpiry(namespace string) (string, error) {
306335
307336// IsReadOnly returns whether or not the connection macaroon is read-only.
308337func IsReadOnly (namespace string ) bool {
338+ mMutex .Lock ()
339+ defer mMutex .Unlock ()
340+
309341 if m [namespace ].mac == nil {
310342 log .Errorf ("macaroon not obtained yet. IsReadOnly should " +
311343 "only be called once the connection is complete" )
@@ -326,6 +358,9 @@ func IsReadOnly(namespace string) bool {
326358// HasPermissions returns whether or not the connection macaroon
327359// has a specificed permission.
328360func HasPermissions (namespace , permission string ) bool {
361+ mMutex .Lock ()
362+ defer mMutex .Unlock ()
363+
329364 if permission == "" {
330365 return false
331366 }
0 commit comments