In the discussion above, I used the telnet command as an example of one of the programs that use TCP/IP. However, there are many others which provide additional services such as transferring files, electronic mail, networking printing, and access to remote filesystems. Other products, such as database applications may have one central machine containing all the data and access is gained from the other machines via TCP/IP. Often this access is invisible to the user who just sees the “front end” of the database.
This configuration, where one machine contains the data or resource that an other machine uses is very common in computer networking. The machine with the resource that it is providing to other machines is referred to as the server, because it is serving the resource to the other machine. The machine that is using the resource is called the client. This model, where one machine is the server and the other is the client is referred to as a client-server model.
Another common network model is the peer-to-peer model. In this model, there is no one central machine that has all the resources. Instead, all machines are on equal status. Often times, these two models sort of blend together. In Linux networks, it is possible to have multiple servers, each providing many of the same resources. In can also happen that multiple machines all have resources that the others need so everyone is acting as both a client and a server, similar to peer-to-peer, which is common in Microsoft Windows networks.
On Linux systems, there are dozens of resources available. Many of which are well-known such as telnet, others, such as ntp are more obscure. Like calling into a large office building with a central switchboard, our server needs to know what numbers are associated with which programs in order to make the proper connection. In the same regard, you need to know what office you want to reach before you call. In some cases you can call and say you want a particular extension. In other cases, you say you want a particular office. In a office building there is a list of available “services”, called a phone book. On a Linux system the phone book is the file /etc/services.
The /etc/services file contains a list of what services a particular machine may have to offer. The concept of a service is slightly different than the concept of a resource. A machine may provide many resources in the form of login shells that it provides to remote users, however all of them are accessing the machine through the one service: telnet.
In addition to what service the machine provides, /etc/services also lists the port. To understand the idea of a port, think about this as being the telephone number. When I call in to a machine (say using telnet), I am connected to the telnet program on the other side through a particular port. This is as if I were calling a large office building with a single switchboard. When I reach that switchboard, I tell the operator which office or person I want to talk to. In the ancient history of telephones, that operator had to make the connection between the incoming line and the office herself.
A port can also be thought of as the socket that the operator plugs the phone lines into. Like in that office building, there may be a set of these sockets, or ports, that are directly connected to a specific person (i.e. service). These are well-known ports. There may be offices with their own operator (maybe just a receptionist) who passes the incoming phone call to the right person or may even pick someone themselves to take the call (such as when you call a government agency with a generic question and there is no one person responsible for that area).
On a Linux system using TCP/IP, the principle is the same. There are dozens of services that one can connect to, but only one way into the system, that’s through your network interface card. In order for you to be able to connect to the right service, there has to be something like an operator to make the connection for you. This is the program /etc/inetd. This is the “Internet Daemon” and often referred to as a “super server” since it is inetd’s responsibility to wait for requests to access the other servers on your system and pass you along.
Like in our office building, you may know what number you want, that is, which port. When you make the connection to inetd, your process tells it what port you want to connect to and inetd makes the connection. On the other hand, you may have a program that does not have a well-known port. Therefore a new port needs to be defined.
The inetd daemon “listens” for the incoming connections. You can say that it is listening on multiple ports in the sense that it manages all the ports. However, it is inetd that makes the connection between the incoming connection and the local port, and therefore to the local server. This mechanism saves memory since you don’t need to start up the servers you aren’t going to use. This is similar to having a central switchboard and not requiring every office to have their own. You can see how this looks graphically here:
Normally, inetd is started during system start up from a script under /etc/rc.d. When it starts,
inetd reads its configuration file (/etc/inetd.conf) to obtain the necessary information to start
the various servers. It then builds the logical connection between the server and its respective
port. Kind of like laying the cable from the central switchboard to the various offices. Technically
it creates a socket, which is
When inetd gets a connection request (the phone rings) for a connection-based port, it “accepts” the incoming call which creates a new socket. That is, there is a logical connection between the incoming request and the server. Inetd can now continue to listen on the original port for addition incoming calls.
Note that the inetd will start the program listed in /etc/inetd.conf based on the port requested (which is listed in /etc/services). However, if the appropriate program is already running, there is no need for inetd to start it. Therefore, you may have an entry in /etc/services, but not in /etc/inetd.conf. Services that are not started by inetd are usually referred to as “stand-alone” services. You may have case (like HTTP or FTP) where the program (i.e. the service) is already running, there is no entry in /etc/services. This is because such services us well-known ports and typically nothing else is going to try to use them. However, if you have a “non-standard” program using a special port, then it needs to write an entry in /etc/services to ensure that other programs do not inadvertently use that port.
Like with the telephone analogy, you might have a busy single or the system does not answer. A busy signal would indicate that a remote machine is already using the particular service. This general does not happen because most services can handle multiple connections. It might also be that there is no answer, in which case you would get a ‘connection refused’ refsued message from inetd. This happens when the the particular services is not configured in /etc/inetd.confc or perhaps not configured correctly. When that happens, inetd does not know what to do an simply refuses the connection.