Skip to content

Commit c2e2294

Browse files
fix: avoid concurrent requests for getting RSD service for a device
1 parent 4120842 commit c2e2294

File tree

1 file changed

+16
-0
lines changed

1 file changed

+16
-0
lines changed

ios/rsd.go

+16
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,16 @@ import (
66
"io"
77
"net"
88
"strconv"
9+
"sync"
910

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

16+
// _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.
17+
var _requestsMap = sync.Map{}
18+
1519
// 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.
1620
// Used in iOS17+
1721
type RsdPortProvider interface {
@@ -163,6 +167,12 @@ func (r RsdHandshakeResponse) GetServices() map[string]RsdServiceEntry {
163167
// NewWithAddrPort creates a new RsdService with the given address and port 58783 using a HTTP2 based XPC connection,
164168
// connecting to an operating system level TUN device.
165169
func NewWithAddrPort(addr string, port int) (RsdService, error) {
170+
key := fmt.Sprintf("%s-%d", addr, port)
171+
172+
mutex, _ := _requestsMap.LoadOrStore(key, &sync.Mutex{})
173+
174+
mutex.(*sync.Mutex).Lock()
175+
defer mutex.(*sync.Mutex).Unlock()
166176
conn, err := connectTUN(addr, port)
167177
if err != nil {
168178
return RsdService{}, fmt.Errorf("NewWithAddrPort: failed to connect to device: %w", err)
@@ -177,6 +187,12 @@ func NewWithAddrDevice(addr string, d DeviceEntry) (RsdService, error) {
177187

178188
// NewWithAddrPortDevice creates a new RsdService with the given address and port using a HTTP2 based XPC connection.
179189
func NewWithAddrPortDevice(addr string, port int, d DeviceEntry) (RsdService, error) {
190+
key := fmt.Sprintf("%s-%d-%d", addr, port, d.UserspaceTUNPort)
191+
192+
mutex, _ := _requestsMap.LoadOrStore(key, &sync.Mutex{})
193+
194+
mutex.(*sync.Mutex).Lock()
195+
defer mutex.(*sync.Mutex).Unlock()
180196
conn, err := ConnectTUNDevice(addr, port, d)
181197
if err != nil {
182198
return RsdService{}, fmt.Errorf("NewWithAddrPortTUNDevice: failed to connect to device: %w", err)

0 commit comments

Comments
 (0)