Search code examples
iossocketsios-extensionsunix-socket

Binding a Unix Domain Socket from within an iOS extension fails with errno 48 (Address already in use)


I have some logic which works by creating a Unix Domain Socket and doesn't have any issues when run within a normal app. However, when I run this for an app extension I get a -1 with errno = 48 ("Address already in use") from the bind().

NSArray *applicationSupportDirectoryPaths = 
NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,
                                    NSUserDomainMask, YES);

int fd = socket(AF_UNIX, SOCK_STREAM, 0); // returns a non-zero value

NSString *loc = [applicationSupportDirectoryPaths[0] stringByAppendingPathComponent:@"usd"];
struct sockaddr_un addr;
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX   ;
strncpy(addr.sun_path, [loc UTF8String], sizeof(addr.sun_path)-1);
int bindres = bind(fd, (struct sockaddr*)&addr, sizeof(addr)); // returns -1, error is 48

The location returned for the library directory is:

/var/mobile/Containers/Data/PluginKitPlugin/A8110BA2-5AE7-42C1-84DA-2A9B303C7277/Library/

I think the reason this is failing is because this is some special location, as compared to the library directory for an app.

If anyone has any ideas why this is happening or any workarounds, I appreciate it.

UPDATE: I tried with the caches directory (NSCachesDirectory), but now I get errno 3 (no such process).


Solution

  • First guess is address really is in use.

    iOS might instantiate/kill extensions on demand, so the socket bound in the previous call might be not released when the next call is performed.