How can I launch multiple instances of an application using launchd? - launchd

My application is split into two parts. The main application and a helper tool. The helper tool performs a task with elevated permissions.
The launchd plist looks like this: (Only important settings included.)
<key>UserName</key>
<string>root</string>
<key>ProgramArguments</key>
<array>
<string>/Library/PrivilegedHelperTools/helperTool</string>
</array>
<key>Sockets</key>
<dict>
<key>IPC</key>
<dict>
<key>SockPathName</key>
<string>/tmp/TheSocket</string>
</dict>
</dict>
Is there a way to launch a new helper instance for every connection to the socket?
Or alternatively, is there a existing template for handling multiple requests? (I'm doing this myself at the moment, which is quite a lot of ugly code.)

This will probably be my first answer in Stackoverflow :)
First, Set inetdCompatibility with Wait to false.
This will make launchd to accept the socket.
<key>inetdCompatibility</key>
<dict>
<key>Instances</key>
<integer>42</integer>
<key>Wait</key>
<false/>
</dict>
Once, launchd accepted the socket. The accepted to socket will be passed into your program as STDIN_FILENO. Your launchd process can access the accepted the socket as follows: (I copied the code from open source sshd)
int sock_in;
int sock_out;
sock_in = sock_out = dup(STDIN_FILENO);
NSLog(#"socket descriptor: %d", sock_in);
The sock_in is already accepted. So your program can use it without calling accept.
I am assuming you already have a plist which will monitor a socket port for you. If not, it's possible to do that as follows. It will create a launchd socket listen for port 18411 with IPv4 TCP.
<key>Sockets</key>
<dict>
<key>Listeners</key>
<dict>
<key>SockServiceName</key>
<string>18411</string>
<key>SockType</key>
<string>stream</string>
<key>SockFamily</key>
<string>IPv4</string>
</dict>
</dict>

Related

How to add entitlements to a command line program written in C

I'm creating a command line program written in the C language in the usual way — compiling with gcc on the command line etc. I want my program to be able to use Hypervisor.framework. In order to do this it needs the com.apple.security.hypervisor entitlement. How can I add this entitlement to my compiled binary in order to allow it to run?
Sorry to resurrect an old thread, an alternate way is to link it in:
zpool_LDFLAGS = -sectcreate __TEXT __info_plist yourcmd-Info.plist
zpool_LDFLAGS += -sectcreate __TEXT __entitlements yourcmd-entitlements.plist
You'll need something like this (although with a different <key> for your entitlement): https://glyph.twistedmatrix.com/2018/01/shipping-pygame-mac-app.html
Pasted here:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
</dict>
</plist>
Save in entitleme.plist, and then run:
codesign --sign - \
--entitlements entitleme.plist \
--deep <your-binary> \
--force
other reference to homebrew issue on codesigning in general: https://github.com/Homebrew/brew/issues/9082

How to run SRT server on local?

I want to create a streaming application which is responsible for send and receive live audio/video stream.
But this audio/video stream must be equipped with FEC client server error mechanism. I have done some R&D and found that Haivision has provided open source SRT solution.
I have setup project as suggested here https://github.com/Haivision/srt but no idea how to run this server.
Please guide me how can i start this server. Reply me as soon as possible.
The SRT library is provided with API guides to allow you build it into your own applications and 'hubs', rather than a ready to go 'server' that you configure and run.
The API includes information on how to 'start' SRT and on how to set up a socket to listen for traffic - e.g.:
Setup and teardown
Before any part of the SRT C API can be used, the user should call srt_startup() function. Likewise, before the application exits, the srt_cleanup() function should be called. Note that one of the things the startup function does is to create a new thread, so choose the point of execution for these functions carefully.
SRT Usage - listener (server)
sockaddr_in sa = { ... }; // set local listening port and possibly interface's IP
int st = srt_bind(sock, (sockaddr*)&sa, sizeof sa);
srt_listen(sock, 5);
while ( !finish ) {
socklen_t sa_len = sizeof sa;
newsocket = srt_accept(sock, (sockaddr*)&sa, &sa_len);
HandleNewClient(newsocket, sa);
}
The info is all in the API section of the link you highlighted: https://github.com/Haivision/srt/blob/master/docs/API.md
There is (at the time of writing) a guide to using the SRT library with ffmpeg to send and receive data - this may be what you are looking for: https://medium.com/#eyevinntechnology/using-ffmpeg-and-srt-to-transport-video-signal-to-the-cloud-7160960f846a

3 sockets created for one libevent bind on Windows?

I'm writing a BitTorrent client to learn some more about networking, and I've got something that I'm struggling to Google for. As part of the BT spec, I need a server to listen for peer connections to my computer. In the win32 port, I have code like this to setup my server
struct sockaddr_in saServer;
struct hostent* localHost;
char* localIP;
// Get the local host information
localHost = gethostbyname("");
localIP = inet_ntoa(*(struct in_addr *)*localHost->h_addr_list);
saServer.sin_family = AF_INET;
saServer.sin_addr.s_addr = inet_addr(localIP);
saServer.sin_port = htons(6881);
struct evconnlistener *listener = evconnlistener_new_bind(base, accept_conn_cb, NULL,
LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, -1, (SOCKADDR*)&saServer, sizeof(saServer));
That seems to work, but if I look at netstat, I see the following,
BitTorrentClient.exe 6092 TCP hostname 50216 localhost 50217 ESTABLISHED
BitTorrentClient.exe 6092 TCP hostname 50217 localhost 50216 ESTABLISHED
BitTorrentClient.exe 6092 TCP hostname.home 6881 hostname 0 LISTENING
Why are there two other connections, one from port 50216->50217 and one looping back from 50217->50216? I was expected to have just one listening connection on port 6881. Is this a libevent quirk, or something more fundamental related to networking?
What can I search for to understand what the other two ports are used for?
This is most likely a result of libevent calling evutil_make_internal_pipe_ internally.
Libevent creates internal "pipes" for inter-thread communication and signal delivery using socketpair(2) on POSIX-compliant systems, whereas on Windows libevent has to resort to manually connecting two sockets together instead.

Is Unix socket's, sockaddr_un.sun_path case sensitive?

struct sockaddr_un serverUNIXAddress;
The following code works under Mac OS 10.9, but not under Linux. It doesn't die on either, but writing from the client to the server, only works under Mac OS. I fully understand that it shouldn't work on either. Why does it work under Mac OS? Is this a bug in the socket implementation, or just a peculiarity that makes it difficult to port, if the bug is not caught?
client.c
//Server domain
serverUNIXAddress.sun_family = AF_UNIX;
//Server name
strcpy(serverUNIXAddress.sun_path, "rockPaperScissors");
server.c
strcpy(serverUNIXAddress.sun_path, "RockPaperScissors");
//Create file
bind(serverFd, serverSockAddrPtr, serverLen);
//Maximum pending connection length
listen (serverFd, 5);
////[...]
A Unix domain socket file is created in the file system. The default file system on OS X is case-insensitive. Therefore, the client finds the server's socket using a case-insensitive match.
You can use case-sensitive file systems on OS X. If you did and created your socket file there, then the matching would be case-sensitive, too.
I assume Linux supports case-insensitive file systems. If you used one of those and created your socket file on it, then the matching would be case-insensitive.

error in binding port "Address already in use" TCP socket programming in unix

I've gone through many posts and forums and I'm new to socket programming. Major parts of my code are similar to
BIND ERROR : Address already in use
but then i changed my code so that i include "setsockopt" function like so:
const char* port="5555";
int opt=1;
portno=atoi(port);
//parameters for server address
serv_addr.sin_family=AF_INET;
serv_addr.sin_port=htons(portno);
serv_addr.sin_addr.s_addr=INADDR_ANY;
//bind the socket to the address
setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,(const char *)&opt,sizeof(int));
if(bind(sockfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr))<0)
{close(sockfd);
error("error in binding port!");
}
But still i get the error. I have to close the terminal and restart it in order to use the port again. I want to use a hardcoded port (like i mentioned in the code above)
Thanks a lot in advance
Check to see if the port is in use. Either telnet to that port or use netstat -a. It should be in use (as the error indicates) and kill the appropriate process. Perhaps using ps to find the process.
A port number can only be used by one application at a time. That means you can not start the same program twice expecting both to bind to the same port.
The SO_REUSEADDR is for when the socket bound to an address has already been closed, the same address (ip-address/port pair) can be used again directly.

Resources