Skip to content

Commit 5c902ce

Browse files
fix: avoid concurrent requests for getting RSD service for a device
1 parent 5403671 commit 5c902ce

File tree

1 file changed

+11
-0
lines changed

1 file changed

+11
-0
lines changed

ios/rsd.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,16 @@ import (
55
"fmt"
66
"io"
77
"strconv"
8+
"sync"
89

910
"github.com/danielpaulus/go-ios/ios/http"
1011
"github.com/danielpaulus/go-ios/ios/xpc"
1112
log "github.com/sirupsen/logrus"
1213
)
1314

15+
// _requestsMap stores a mutex for every request attempt to the trio formed by address, port, and TUN port. This allows to make sure that no more than one request is made at a time to a given trio, since doing so can lead to stuck requests and, therefore, stuck programs and/or goroutine leaks.
16+
var _requestsMap = sync.Map{}
17+
1418
// RsdPortProvider is an interface to get a port for a service, or a service for a port from the Remote Service Discovery on the device.
1519
// Used in iOS17+
1620
type RsdPortProvider interface {
@@ -146,6 +150,13 @@ func NewWithAddr(addr string, d DeviceEntry) (RsdService, error) {
146150

147151
// NewWithAddrPort creates a new RsdService with the given address and port using a HTTP2 based XPC connection.
148152
func NewWithAddrPort(addr string, port int, d DeviceEntry) (RsdService, error) {
153+
key := fmt.Sprintf("%s-%d-%d", addr, port, d.UserspaceTUNPort)
154+
155+
mutex, _ := _requestsMap.LoadOrStore(key, &sync.Mutex{})
156+
157+
mutex.(*sync.Mutex).Lock()
158+
defer mutex.(*sync.Mutex).Unlock()
159+
149160
conn, err := ConnectTUNDevice(addr, port, d)
150161
if err != nil {
151162
return RsdService{}, fmt.Errorf("NewWithAddrPort: failed to connect to device: %w", err)

0 commit comments

Comments
 (0)