Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linux: How to make a daemon/service usable with xinetd?

Anybody knows what changes are necessary for a server to work with xinetd ?

The server being a .NET mailserver that runs on Linux.

See the bottom of this post for reference: Lumisoft Mailserver Forum Post

Note: xinetd, not mono-service. [x]inetd is an internet superserver.
A superserver starts a server service on demand.
(As opposed to the server service running continuously, which is what mono-service does)

like image 690
Stefan Steiger Avatar asked Aug 18 '10 17:08

Stefan Steiger


2 Answers

An inetd service runs differently from a standalone server. inetd services read stdin and write to stdout, letting inetd handle the gory details of TCP/IP, rather than keeping track of their own sockets. If you want to make a server run under inetd, it'll have to do the same.

The following program runs just fine under xinetd on my machine:

#include <iostream>
#include <string>

using namespace std;  // yeah, i'm lazy.

int main()
{
    string name;
    cout << "What's your name? " << flush;
    cin >> name;
    cout << "Hi, " << name << "!" << endl;
}

Note i'm not at all worried about sockets -- xinetd arranges things so that the service can read standard input and write to standard output. You just write your app like you'd be running it on the console, for the most part. The socket details are specified in the config file for the service. (Note, you might be able to get/set details about the socket using stdin/stdout, which may be the actual socket -- i'm not sure -- but you really should leave that stuff up to inetd.)

like image 80
cHao Avatar answered Nov 12 '22 15:11

cHao


An inetd services are really great for one off apps that need to take in data and act with some degree of interaction with the user. IT works over tcp/udp by piping the data viva a socket from (x)inetd to std{in,out,err}. inetd apps also works well with tcpwrappers to inhance security though system policy files and ACL.

So yes you would write your app like its a console app since in reality it is a console app. Just think of inetd as a transparent reverse proxy from the network to your app's inputs.

A Word of advice, write your code to handle the process signals correctly and if you need to interact with another process on the system use unix sockets/fifo for that.

Also, don't try to write an app that streams a lot of data all at once or needs a lot of connections. Scalability is an issue as inetd becomes a bottle neck, this is why Apache and Sendmail dropped support for inetd and sit as mono apps instead. HTTP fits this role better and a fastcgi (or insert favorite framework) script with nginx works best for that use case.

A good example for an inetd would be:

lock = Mutex.new

trap :HUP  { #log the connection and cleanup }
trap :USR1 { lock.synchronize do #stuff; end }
trap :TERM { #clean up }
trap :KILL { #clean up and die with error codes }

puts "App name - version"

loop do
  ('%s> ' % Console.prompt).display
  input = gets.chomp
  command, *params = input.split /\s/
  case command
    when /\Ahelp\z/i
      puts App.help_text
    when /\Ado\z/i
      Action.perform *params
    when /\Aquit\z/i
      exit
    else
      puts 'Invalid command'
  end
end
exit

Edit your /etc/services to include your app like this: myapp port#/proto

and add your app to /etc/inetd.conf (or xinetd.d) like this: myapp stream tcp6 nowait myappuser /path/to/myapp myapp -arg_flags

like image 42
Dwight Spencer Avatar answered Nov 12 '22 16:11

Dwight Spencer