several TCP-servers on the same port - java

It looks very strange for me. I can run several TCP servers on the same port.
I use Apache MINA library with following code:
IoAcceptor acceptor = new NioSocketAcceptor();
acceptor.bind(new InetSocketAddress(80));
Port 80 is already used by another program. But I didn't get exception "Address already in use". With netstat I can see following:
C:\>netstat -oan |find /i "LIST"
TCP 0.0.0.0:80 0.0.0.0:0 LISTENING 2220
TCP 0.0.0.0:80 0.0.0.0:0 LISTENING 904
TCP 0.0.0.0:135 0.0.0.0:0 LISTENING 840
Could someone explain me such behaviour?
OS: Windows 7.
Thanks.

Normally only one process can listen on a TCP port, on Windows or any other OS (at least the major ones). On Windows you'd expect to get error code 10048 if two processes share the port. This won't apply if the processes are bound to different interface addresses (even if one is bound to INADDR_ANY and the other is bound to a specific address, they don't clash). Also, this doesn't apply if SO_REUSEADDR has been set on the second socket.
Since both processes are bound to INADDR_ANY and you claim your process hasn't had SO_REUSEADDR set, however, this is a puzzle. As far as I can tell there are three possibilities:
Something in the underlying library is setting SO_REUSEADDR by default.
The second socket was actually opened later and it's the one specifying SO_REUSEADDR.
There is a bug in the Windows sockets layer which allowed this.
I realise no software is perfect, but I really hesitate to choose the third option, especially if you can easily reproduce it. I would suggest carefully watching netstat output before and after starting your process and seeing whether the other listener exists prior to that. Also, try to identify the other process and see whether it's related (you can enable the PID column in the task manager for that).
EDIT
The commenter below has reminded me that I should point out that the behaviour of SO_REUSEADDR does differ across platforms. Windows allows new sockets using the option to forcibly bind to the same port as other listening sockets, with undetermined behaviour if the two sockets are both TCP, as discussed here. In practice the second socket probably "steals" the address, but the official line seems to be that the behaviour is undefined:
Once the second socket has successfully bound, the behavior for all sockets bound to that port is indeterminate. For example, if all of the sockets on the same port provide TCP service, any incoming TCP connection requests over the port cannot be guaranteed to be handled by the correct socket — the behavior is non-deterministic.
Linux (and other Unix variants) will not allow two TCP sockets to share the same port if the old one is still listening. In this case, SO_REUSEADDR only allows the new socket to bind if the old one is in TIME_WAIT (and perhaps the FIN_WAIT and CLOSE_WAIT states, I'd have to check that).
As an aside, I found the difference in behaviour quite surprising when I first came across it in Windows, but I've tested it myself and certainly if you set SO_REUSEADDR on both sockets it's quite possibly to bind successfully to exactly the same address and port simultaneously. I haven't done extensive testing on the exact behaviour in this situation, however, since in my case it didn't matter too much.
I'm not about to get into which platform is "correct", but certainly the Windows behaviour has lead to security issues which is why they came up with the SO_EXCLUSIVEADDRUSE option to prevent other sockets forcibly binding. I've also seem people of the opinion that the Windows version should be regarded as a completely different option, with different behaviour, which just happens to have the same name.

Related

Implications of restricting RMI to one port

I'd like to be able to restrict the ports used by my application to some small-as-possible known set. The application uses Java RMI to communicate with a remote server. The registry is exported on port 1099, which is standard. However, it appears that the port used to export the various remote objects is not always consistent, though it does stay the same across multiple connections over a short period of time. My uneducated guess is there is some sort of caching of the server sockets going on behind the scenes which causes this.
I'd like to be able to ensure that the connection always occurs over a few well-known ports, so that users who install the client application have to open as few ports as possible in their firewall. It seems that I could do this by changing the RMISocketFactory to a custom implementation and override the createServerSocket method to always use a known port. However, this raises a few questions:
How does this affect scalability? It sounds great if I knew only one person would ever connect at a time, but wouldn't it block multiple simultaneous connections?
Is it possible to bind these remote objects on the same port as the registry? My intuition says no, as the port would already be bound by the createRegistry call.
Are there other implications I am ignorant of?
wouldn't it block multiple simultaneous connections?
No.
Is it possible to bind these remote objects on the same port as the registry? My intuition says no, as the port would already be bound by the createRegistry() call.
Yes, as long as you start the registry in the same JVM, via LocateRegistry.createRegistry(), and as long as any server socket factories involved are equal().
Are there other implications I am ignorant of?
There are no implications at all. RMI does port sharing between remote objects with null or equal server socket factories, and TCP does port sharing between multiple connections to the same port.

Finding Open Port TCP Communication

I'm writing a Java application like AIM where I want a lookup server to help two clients connect to each other with the ServerSocket class. Unfortunately a serversocket needs an open port or it will be blocked by your firewall. Without having the clients manually change their firewall settings is there a way I can either find an open port, open a port (it's okay if it asks for permission) I just don't want every client to manually have to change firewall settings. Thanks!
Creating a ServerSocket is what opens the port on the server end (assuming the port is NOT also blocked on the firewall). On many systems, port numbers <1024 are not blocked by the firewall, and therefore often don't require custom configuration. However, since many ISPs have been more and more stringent with what ports they block within their network, many pieces of software have moved to operating over port 80. Why port 80? It's the port used for HTTP, and therefore pretty much open (at firewalls) 100% of the time for any service that operates on the web.
To answer the question of how to find an open port, port scanners perform this function. Basically all they do is try to establish a connection on a range of ports (say port 1-1024). When a connection is successful (in Java you would see this as a good connection over a Socket), you can consider that port "open". You don't need to exchange any data in order to make the connection, you just need to establish the connection, and then close it.
Also, if there is no server software of any kind running on the server, it won't appear "open", even if it isn't blocked. Without a successful Socket (TCP) connection, you won't know what ports are not blocked by user's firewall.
To reiterate, I'm switching back and forth between two related, but separate concepts. Firewalls can block/open ports, or have port forwarding. That's not the same as a port being "open" for connections on a given machine. In order for a machine to accept connections on a given port, there must be a piece of software listening for a connection on that port, otherwise no connection can be made.
I would suggest to look at a couple of alternative solutions that are less cumbersome - scanning for open ports can take quite some time, can cause panicky reactions from firewalls that feel attacked, and so on. There are a couple of techniques that are in active use and have been developed exactly to solve the problem of servers behind firewalls.
UDP Hole Punching, zero user side configuration needed. Simple explanation on how Skype uses this technique can be found here
UPnP / IGD could be used as an alternative, though less devices support it out of the box nowadays due to security problems.
STUN with a Java implementation of client and serverside called JSTUN
Whatever solution you choose, test it thoroughly with different internet service providers, there's a plethora of limitations you can expect wrt blocked ports.

BACNet plugin for Building Management System

I'm trying to get a BACNet scanner up on an Seimens server running the Apogee system with a BACNet interface. I've tried using BACNet4j put i get a port bind error on the LocalDevice object for test/Scan.java.
Does anyone know of any other libraries I could use or a reference to instructions for setting up a BACNet plugin to a building management system?
I have had the same problem before, i.e. the BACnet client needs to both send and receive from UDP port 47808. Since the BACnet server already uses that port to listen (and reply) my solution was to use a virtual IP (a bridge) so that my client runs on the same Ethernet card but with a different IP address. A bit convoluted, I know, but it works.
Whether or not the Apogee system supports virtual (or simply additional) network drivers is another question altogether. On my Linux and Windows machines I can run as many servers and clients as I need (I actually don't know what is the limit, I have run up to 5 servers and 3 clients without any problems).
Concerning the port bind error, you may have to configure your firewall because:
BACnet/IP is using UDP
the default port number is 47808 (0xBAC0)
Your issue might be the use of a (BACnet port #) socket that is already in-use; you have to ensure that it's not in exclusive-use - before binding to the socket, but also (slightly more) important, also ensure it's marked for reuse.
But unless you're listening for Who-Is broadcasts, I'd recommend listening for the (unicast) responses upon a different port #, e.g. 0xBAC1/47809, but still send upon the standard port # 0xBAC0/47808.

Java: How to clear socket bindings

I am having a few issues with sockets within my Java SIP client. When I bind to an address and port, if something goes wrong I have to attempt to reconnect, usually after I've stopped and restarted the process. Problem with that is then the port is bound and I am forced to increment the local port.
How can I remove the binding to the port I am targeting before binding to it?
If that isnt possible, then how can I trap the process just before it ends so that I can locate the socket binding and close it manually?
#Jason - Jason, but in this case I am writing the Client and have no access to the server, the port I am referring to is on the client and is local. Is there a way to flush the port binding before attempting to connect? If not is there a way to trap the process interrupt, as in perl there is a way to trap a 'die' signal and do some post processing, does Java have this? If so I could call close() on the socket connection
In my experience 9 times out of 10, the answer to this class of problem is, "Look up SO_LINGER".
If you pull the plug (literally) on a client, the server optimistically hopes it will come back to collect the data you already sent on that socket. So it holds onto that data, and the port, until the buffers clear.
Usually on the server you want to kill these buffers with extreme prejudice, due to the sort of DOS attack (intentional or accidental) you just discovered.
Don't fiddle with SO_LINGER, it just adds insecurity. The real question is why are you binding to a local port at all?
Ok - I found a way to trap Java signals by reading this tutorial online - http://www.ibm.com/developerworks/java/library/i-signalhandling/
This way one can trap the die signal and close the connection.

How can I work around WinXP using ports 1025-5000 as ephemeral?

If you create a TCP client socket with port 0 instead of a non-zero port, then the operating system chooses any free ephemeral port for you. Most OSes choose ephemeral ports from the IANA dynamic port range of 49152-65535. However in Windows Server 2003 and earlier (including XP) Microsoft used ports 1025-5000 as the ephemeral range, according to their bind() documentation.
I run multiple Java services on the same hardware. On rare occasions, this range collides with well-known ports that I use for other services (e.g. port 4160 for Jini discovery). While rare, this has caused real problems. Is there any easy way to tell Windows or Java to use a different port range for client sockets? Microsoft's docs indicate that I can change the high end of that range via the MaxUserPort TcpIP registry setting, but I see no way to change the low end.
Update: I've made some progress on this. It looks like Microsoft has a concept of reserved ports that are exceptions to the ephemeral port range. There's a registry setting that lets you change this permanently and apparently there must be an API to do the same thing because there's a data structure that holds high/low values for reserved port ranges, but I can't find the actual function call anywhere... The registry solution may work, but now I'm fixated on this API.
Update2: I accepted a solution on ServerFault for how to do this via the Windows registry. I'd still like a way to do it via API, but I guess I'm satisfied for now.
It's not as elegant as using OS support for ephemeral ports, but the docs show that you should be able to specify a port for your socket to bind to. Specify a port at the base of the range you want and if it is used an exception will be thrown, in which case increment the port and try again. Given that windows isn't using the port range that you want, there shouldn't be many collisions.

Categories