Cross-platform way of communcation between processes in C webserver - c

I made a simple webserver in C now with config implementation. Now, I want to add feature to manage server by calling same process with command line arguments. Like Nginx for example: nginx -s reload will send signal to server and it will reload config from file. I want to achieve the same. But how? In Linux, I can send a signal to server master process by getting PID from pidfile. But how to make it in Windows? Or maybe there is another way?

You can listen on a fixed port number with loopback interface for IPC. There are many cross-platform libraries like libuv and nanomsg.
--
Another method is to use some abstraction provided by a library. For example, still libuv and nanomsg. (Both use domain socket on Unix and named pipes on Windows.)

Related

Handling multiple ptys from a single process without direct protocol I/O

I am considering writing a BBS-like program in C and thinking about exactly how the I/O architecture would work with such a program. I'm familiar with sockets programming already, more specifically the master/remote model (not sure if there's a more official name for it) where a master process running as a daemon runs the vast majority of the application in a main process. When remote TTYs connect, they do so in a separate process that communicates with the main process via a Unix domain socket, and there's a thread on the main process for each remote TTY's I/O. All the modules and functionality are running in the main process.
This works well for things like CLIs for some kind of process, but I don't think it's as well suited for a significantly richer/more interactive program, where I think it'd make much more sense for all the TTYs to be managed in the same process rather than communicating over a socket. For example, you can't run ncurses over a socket, since the termios that we care about is in that remote process, not in our main process or usable over the socket. So taking the master/remote model further, you'd need to move a lot of logic from the main program to the remote processes.
The problem I'm a little stuck on is exactly how you can have the main process handling all the TTYs without itself handling all of the network socket traffic. For example, say we want to allow telnet and SSH connections. With the master/remote model, it might look like this:
Telnet:
Inbound telnet connection
Telnet server launches /usr/sbin/remote_process (custom login shell)
remote_process (a C program, shell script, etc.) begins executing, communicating with main_process
SSH:
Inbound SSH connection
Authentication
SSH server launches /usr/sbin/remote_process (custom login shell)
remote_process (a C program, shell script, etc.) begins executing, communicating with main_process
Importantly, with the master/remote model we consider above, the telnet/SSH protocol is abstracted away from the program in question. It doesn't care if the incoming connection is from Telnet, SSH, a serial port, etc. We don't need to handle the details of these protocols ourselves.
Naively trying to apply this to the single-process model, handling all the TTYs directly, I would think the thing to do would be that step # 3/4 somehow needs to have the main process take over its terminal/PTY. main_process can't be called directly though, since it's already running, and I'm not sure if anything like that would be possible since somehow it would be moving the master/slave for the pty between processes, but the goal would be to have main_process doing everything remote_process was doing in the other model, directly handling the I/O from the Telnet server, SSH server, etc.
The standard way of doing this kind of thing seems to be having the main_process directly run its own listeners - that is, instead of listening for UNIX domain socket connections, directly accept Telnet/SSH traffic, etc. But then, the program is now responsible for handling the details of each individual protocol.
You can see an example of this with SyncrhonetBBS: https://github.com/SynchronetBBS/sbbs/tree/b35365c2e470bde58838cbb7445fe7e8c4bc1beb/src/syncterm
The BBS program itself has code to handle each supported protocol: SSH, TELNET, TELNETS, etc.
(I suppose there is a third model: have the main daemon process itself be quite minimal in what it does, and just have each individual TTY process contain the bulk of all the logic, and just use the daemon process for IPC between the TTYs... but then that gets tricky if you want to do stuff like dynamically loadable and unloadable modules that are really at a "system" level as opposed to per-TTY... so I'm not really considering this other extreme).
Is there any way to have the best of both worlds - be able to control all the different TTYs from a single process, but without having to directly implement protocol-specific handling? And if so, how does the TTY setup occur? I'm not looking for code examples here so much as a general high-level explanation/guidance of what this would likely look and how the different components - processes, sockets, TTYs - would interact.

upgrade server executable without losing user's connections

I need to develop a mechanism to upgrade a running daemon in production environment to a new version without losing client's (TCP) connections. Something similar to what nginx does when you upgrade it to a new version. I need this for bug removal or to release minor version changes, which may be once a day. The daemon is developed in C for Linux platform.
The process for the upgrade would be like this:
The new_daemon would be ran from the command line specifying the process id of the old_daemon
The new_daemon would connect via socket to the old daemon to send/receive data and mesages.
The new_daemon would send the old_daemon a message to stop listening on the PORT which is used to receive client's connections. After confirming the detention of the listening service, the new_daemon would start listening on PORT
The new_daemon would send the message to old_daemon to send currently open file descriptors of the user's connections. Using the system call sendmsg() the old_daemon would pass the new_daemon all resources it has allocated with the kernel, not only the connections, but also all open files.
The new_daemon would send the message to old_daemon to pass all global memory variables and the old_daemon would send it over the socket connection between both processes.
This process is very complex, so I would like to ask if someone can suggest a better process or maybe there is some methodology to do this easily? The goal is to have the least downtime during the upgrade process.
TIA
Another alternative is to force the old_daemon to fork()/exec() the new_daemon and immediately stop accepting. The new_daemon would inherit the listening socket, existing connections, and open files (unless they are fcntl'd to FD_CLOEXEC) automagically.
That said, I don't think there is a clean way to hand over incomplete jobs (as I understand steps 4 and 5 try to accomplish). If possible, let the old_daemon complete them.
One alternative is to write most of your demon as a shared library and use dlopen to link the new functions into the running process. This means some parts can't be changed and you might have concurrency issues but it removes the need for IPC.

Communication between Linux programs

how would I implement communication between Linux programs written in C? Specifically, I want the following:
My program can run in multiple instances. Upon startup, I want that my program detects all other instances of my program that are already running and then it should be able to send a text string to them. On the other hand, I also want that the instances that are already running get notified that a new instance has been started and they should also be able to send a text string to the new instance.
Could someone point me to some APIs which could be used to implement such a software design on Linux? On Windows, I can simply enumerate over all windows, check their class names to find out all instances of my program, and then register a custom message with the system that I can use to send data to them. But how would I do this on Linux?
Thanks for any hints!
You have a lot of options:
Named pipes;
Msg commands (msgget, msgsend);
Using TCP sockets;
Using UNIX domain sockets;
Using a third party broker, like DBus or ActiveMQ;
If it is for a standalone machine, and only one stream of data, I would recommend the option number 1.
1st pointer: The Linux Kernel: IPC Mechanisms
2nd pointer: Detailed documentation on using shared memory
I would probably start with named pipes
I have used sockets and multicast for that very purpose. This allows distribution of processes among several computers on the same LAN.

Interprocess communication with a Daemon

I want to implement a Unix daemon (let's call it myUnixd), and want the user to be able to interact with this daemon via the command line, for example:
myUnixd --help # will display help information
myUnixd --show # will show some data (the's deamon should be doing the work)
So my question is: How can I communicate with the daemon? I was thinking about Unix domain sockets. Can someone tell me the right way to do this?
Thanks.
Use Berkeley sockets. Specifically, you can create a "UNIX domain socket" (otherwise known as a "local domain socket," which will create what looks like a text file. Write to the text file to send text to the daemon, read from it to receive text from the daemon. You can implement this with a few function calls.
If you want something more advanced, you can also use DBus, which offers a more sophisticated interface, but which is more complicated to learn.
use tcp socket if you want to use telnet to communicate with your daemon.
One could also use Remote Procedure Call (RPC) for such client-server communication. There are different types of messages (protocols) that can be used together with it, one of them is JSON.
The JSON-RPC protocol is very well accepted for such tasks. You can find different tools and libraries to embed in your software. A quick search on google gives this C library. The advantage of such libraries is that from a JSON specification file, where you define all your remote function calls, it creates client and/or server stubs that you can just use in your code out of the box.
As a listener one can use sockets, as the other responses state, or just an embedded HTTP server like microhttpd (and libcurl for the client). There are plenty of examples out there to just reuse. HTTP allows you also to run your client behind a proxy.

Communication between two application in the same local machine

I am using C language and Linux as my programming platform.
I am developing a user-space application that runs in a background, like a daemon. And my problem is, I want another user-space application to communicate with this daemon.
I know that I have to use Interprocess Communication method but I don't know what is the correct implementation.
But using IPC in my communication implementation is my other option. Actually I just want to change the attribute of my daemon by using another application. Please see below a senario:
My daemon runs in a background.
Then some application will control the properties of a daemon, like sleeping delay time.
My first option is by accessing a file with the values of the properties. So that my deamon will poll that values. While the other application will change that values.
I am not sure the efficiency of my options. Please advice.
THanks.
Updating the config file and sending a signal to cause re-read is a standard practise, cheap and easy.
You're looking for D-Bus. Store the initial values in a file, then listen over D-Bus for requests to change it.
Unix domain sockets are a simple IPC method.
If I were you, I'd forego IPC completely and instead have the daemon monitor a config file for changes. IPC is only really needed if you're going to be sending thousands of messages per second and the overhead would get intolerable.
inotify is an option for file monitoring.
I'd make the daemon listen on a pipe/fifo if it's simple enough that you only need to read a couple of bytes fed in from another program. Otherwise a local domain socket is nice to run a simple protocol over.

Resources