Linux - NetworkingThis forum is for any issue related to networks or networking.
Routing, network cards, OSI, etc. Anything is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I'm wondering if there is a way to have a process listen on a single socket which is bound in a way that allows it to accept all connections coming to any port number that is not already specifically bound to some other socket. This process would have full root permissions.
It will need to know to which port the connection was made. So a translation mechanism like I have seen mentioned using iptables might not work. And such a translation mechanism is likely to also break the ability for other ports to go to the appropriate processes doing specific port listening (e.g. 25 to SMTP, 80 to HTTP, 143 to IMAP, and so on).
Indeed there is. You've just described inetd/xinetd.
So how would you configure it to do a listen on all ports with a single socket? If it can do that, then why not program my process to do so.
FYI, I'm expecting a syscall interface solution, such as the bind() call, or library functions related to it to fill in socket name structures. If inetd can do this, then I would just look into what it is actually doing when so configured. But all the documentation for inetd I have has no means to do this.
Last edited by Skaperen; 08-08-2012 at 04:02 PM.
Reason: added FYI
Huh? That's the entire point of inetd; it picks up traffic to any port that's not specifically bound to a listening process.
Never heard of such a thing. This is not what inetd does, or was intended to do. It is a generic daemon listener that listens on each port (service, by name) that is configured, then launches a program/script to handle one connection that arrives. Doing a "listen to all ports at once" is a very unusual thing, if even possible at all.
I do not have very many ports open on my Slackware64 13.37 box, but these are open via inetd:
Binding to address 0.0.0.0 gets the generic "listen to all configured interface/addresses". But binding to port 0 gets a random port number substituted. How are you expecting inetd to be able to listen to ANY/ALL ports at once?
I think I see what you mean now. You want a mechanism that creates a socket for multiple ports, but without specifying a specific port, a kind of "default bind".
The problem is that by definition, a "socket" is an endpoint defined by an IP address and a port number, so using a traditional socket won't work. You would have to use a raw socket, which means bypassing everything down to layer 3, including TCP/UDP.
Is it possible to have the IP stack do something whenever an incoming connection is detected on a non-listening port? Apparently yes, because it does something already; it returns an ICMP error. Can it be made to complete a 3-way TCP handshake instead, and then hand off the connection to a process? Not to my knowledge, but I could be wrong.
I think I see what you mean now. You want a mechanism that creates a socket for multiple ports, but without specifying a specific port, a kind of "default bind".
Quote:
Originally Posted by Ser Olmy
The problem is that by definition, a "socket" is an endpoint defined by an IP address and a port number, so using a traditional socket won't work. You would have to use a raw socket, which means bypassing everything down to layer 3, including TCP/UDP.
No, a socket is not defined that way. You are referring to a TCP connection. A socket is merely an API to access an endpoint. There's no reason based on the TCP/IP protocols that you can't have a socket with semantics of "I'll take that incoming connection attempt if no other socket specifically takes it". If no other socket would take it, then a socket flagged to accept any port can take it, and the TCP connection can be set up using the port the connection is trying to connect to as the endpoint port number. Then when the process inquires as to the socket's port number, that port number will be provided.
Quote:
Originally Posted by Ser Olmy
Is it possible to have the IP stack do something whenever an incoming connection is detected on a non-listening port? Apparently yes, because it does something already; it returns an ICMP error. Can it be made to complete a 3-way TCP handshake instead, and then hand off the connection to a process? Not to my knowledge, but I could be wrong.
It returns a TCP response with the R (Reset) flag on. Not ICMP. ICMP would be sent if the host is not reachable.
To implement this feature, it would only take code somewhere after it decided no port-specific listening sockets match, and before it decides to send back the connection reset, to choose the socket which has a matching address and generic port, or if no such socket, then the socket with a generic address and generic port, and set up the connection with that. The question is, HOW to specify in bind() that a socket is to be the generic port one. All 65536 possible values in the 16-bit port field have a meaning (0 means assign a port number, maybe randomly, from within the appropriate range). So something else has to be used to indicate this generic port preference.
No, a socket is not defined that way. You are referring to a TCP connection. A socket is merely an API to access an endpoint.
I was thinking of the definition of a network socket, but you still need an address/port pair to bind a socket to an address when you want to receive a stream (TCP) or a datagram (UDP). From man 7 ip:
Quote:
When a process wants to receive new incoming packets or connections, it should bind a socket to a local interface address using bind(2). Only one IP socket may be bound to any given local (address, port) pair. When INADDR_ANY is specified in the bind call, the socket will be bound to all local interfaces. When listen(2) or connect(2) are called on an unbound socket, it is automatically bound to a random free port with the local address set to INADDR_ANY.
man 2 socket and man 2 bind confirms this.
Quote:
Originally Posted by Skaperen
There's no reason based on the TCP/IP protocols that you can't have a socket with semantics of "I'll take that incoming connection attempt if no other socket specifically takes it".
Agreed, but it seems that's not how bind() is implemented. You either provide a port number for SOCK_STREAM or SOCK_DGRAM, or you use SOCK_RAW.
Quote:
Originally Posted by Skaperen
It returns a TCP response with the R (Reset) flag on. Not ICMP. ICMP would be sent if the host is not reachable.
You're right, it only returns an ICMP error for UDP packets.
Your quoted text is not re-quoting, so I'll just have to not quote in this one.
What the quoted reference for "man 7 ip" says is that you cannot have TWO sockets for the same port on the same address. And that makes sense. If it were allowed there would be an ambiguity. I have done things like bind a socket to ONE address (of many) and port 12345, and bind another to the generic address (0.0.0.0) and port 12345, and the 2nd bind is in error. And that is a correct error because there is a conflict. Depending on system settings, some people run into this unexpectedly when binding to "::0" not realizing it might conflict with an IPv4 binding involving the same port.
But this is not what I want. I want my "generic port" socket to be defined as NOT conflicting with any existing socket. It would be a special case, and should even conflict with another socket of the same special case when the addresses conflict. If binding to "generic address" AND "generic port" then only one can do so.
And only root should be allowed to do this.
Yes, it seems bind() is not implemented this way. But what seems to be, often is not, for many things. Sometimes there are special added cases. For this, maybe it was implemented (and not documented widely) by means of an extra flag in the socket address, or maybe via setsockopt() and not documented. or maybe some magic juggling act can do it.
It can purportedly be done via an iptables rule I found during pre-post Googling. But that causes a translation of any port number to a specific port number and would match up if I bind a socket to that specific port number. But that won't work because I need to know what port the connection is being made to.
SOCK_RAW is not an option because I don't want to re-implement TCP in user space.
I still say there isn't any reason this cannot be done, other that it probably just hasn't been implemented, and there would need to be some agreement on how the desire to make a socket work this way is set up via the syscalls decided on. If I tried to do this implementation, I'd try to make it be a special form of socket name (address and port) that is distinguishable from what can be done already. Since all 65536 port values already have a defined meaning, it would have to be something other.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.